有效的Java作者:Joshua Bloch:第1项 - 静态工厂方法

时间:2011-05-25 18:23:39

标签: java design-patterns factory effective-java

我正在阅读约书亚布洛赫的Effective Java,我对第1项Static Factory Method有疑问。

引用[Bloch,第7页]

  

接口不能有静态方法,   按惯例,静态工厂   名为Type的接口的方法   被放入不可实例化的类中   命名类型。例如,Java   集合框架,提供   不可修改的集合,同步   收藏品等。几乎所有的   这些实现是导出   通过静态工厂方法合二为一   不可实例化的类   (java.util.Collections中)。课程   返回的对象都是   非公开。

确定。查看源代码时,我看到java.util.Collection接口和java.util.Collections类带有私有构造函数(不可实例化的类)。而且我看到不可实例化的类Collections具有所有静态方法,就像Bloch所说的那样。但我没有看到两个班级之间的联系,正如布洛赫所说的那样。

接口不能使用静态方法,因此按照惯例,名为Type的接口的静态工厂方法放在名为Types的不可实例化的类中。

  1. 任何人都可以向我指出明显的事吗?

  2. 当他说

  3. 时是什么意思

    返回的对象的类都是非公开的

    以下是我获取java源代码的地方:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Collection.java?av=f

6 个答案:

答案 0 :(得分:25)

  1. 接口不能使用静态方法,因此按照惯例,名为Type的接口的静态工厂方法放在名为Types 的不可实例化的类中。

    关键是复数''在'Type [s]“上。因此,如果您的接口被调用Foo并且您想要创建一个名为MyFoo的实现,那么您的工厂应该按照惯例调用Foos实例化。

  2. 返回的对象的类都是非公开的

    这意味着从工厂方法返回的对象类具有私有或默认可见性修饰符,如private class MyFoo{}中所示,因此除了工厂方法之外,它们不能通过任何其他方式实例化。因为你不能使用私有内部或包私有类的new运算符构建一个Object,而不是它们的范围(反射旁边)。

  3. e.g:

     public interface Foo{ //interface without plural 's' (question 1)
         public void bar();
     }
     public abstract class Foos(){ // abstract factory with plural 's' (question 1)
        public static Foo createFoo(){
            return new MyFoo();
        }
        private class MyFoo implements Foo{ // a non visible implementation (question 2)
           public void bar(){}
        }
     }
    

答案 1 :(得分:4)

假设您有一个名为List的接口,并且您希望使用静态工厂方法来创建不同类型的列表。您无法在List接口中定义静态工厂方法,因为它是一个接口。所以你要做的就是有一个返回实现List

的类实例的类
public class ListFactory{
  private ListFactory(){}
  public static List makeArrayList(){...}
  public static List makeLinkedList(){...}
  public static List makeCrazyList(){...}
}

你不能这样做

public interface List{
   public static List makeArrayList();
   public static List makeLinkedList();
   public static List makeCrazyList();
}

由于List是界面。

答案 2 :(得分:2)

所以以Collections.unmodifiableList(...)为例。它返回List的一些实现。但是实现类的名称是无关紧要的。此外,所述类仅通过静态工厂方法构造

答案 3 :(得分:2)

public interface Foo
    static public class Factory
        public Foo create(){..}

Foo foo = Foo.Factory.create();

答案 4 :(得分:1)

1)我在这里不明白你的问题。 Collection是界面,Collections有一些工厂方法,例如emptyList

2)例如Collection.emptyList返回的List实例是实现List接口的私有类的实例。

答案 5 :(得分:1)

它只是意味着Collections(和其他类似的)中的静态工厂方法的返回类型是接口类型(例如List)而不是特定的实现类(例如{{1} }),这对用户是不可见的,因为这会使事情变得复杂并增加API的大小。