Эффективная Java От Joshua Bloch: Item1-Статический Заводской Метод

Я читаю Effective Java Джошуа блох и у меня есть вопрос об Item1 Static Factory Method.

цитата[блох, стр. 7]

интерфейсы не могут иметь статические методы, так по соглашению, статическая фабрика методы для интерфейса с именем Type помещаются в класс non-instantiable именованный тип. Например, Java Рамки собраний, обеспечивают немодифицируемые коллекции, синхронизированные коллекции и тому подобное. Почти все из них реализация экспорта через статические методы фабрики в одном неинстантируемый класс (ява.утиль.Коллекции.) Класс возвращенных объектов непубличный.

Ok. Когда посмотрите на исходный код, я вижу java.util.Collection интерфейс и java.util.Collections класс с частным конструктором (не-экземпляр класса). и я вижу, что не-инстанцируемая коллекции класс имеет статические методы, как и то, что сказал Блоха. Но я не вижу связи между этими двумя классами как Сказал блоха

интерфейсы не могут иметь статические методы, поэтому по соглашению статические заводские методы для интерфейса с именем Type помещаются в неинституциональный класс с именем Types.

  1. может ли кто-нибудь указать мне на очевидное?

  2. что это значит, когда он сказал

классы возвращаемых объектов являются непубличными

вот где я получаю java источники: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Collection.java?av=f

6 ответов


  1. интерфейсы не могут иметь статические методы, поэтому по соглашению статические заводские методы для интерфейса с именем Type помещаются в неинституциональный класс с именем Types.

    дело только в множественное число " s " на " тип[s]". Поэтому, если ваш интерфейс называется Foo и вы хотите создать некоторую реализацию под названием MyFoo тогда ваша фабрика с методами для создания экземпляра должна называться Foos by конвенция.

  2. классы возвращаемых объектов являются непубличными

    это означает, что классы объектов, возвращаемых заводскими методами, имеют частный модификатор видимости или модификатор видимости по умолчанию, как в private class MyFoo{} так что они не могут быть созданы любым другим способом, но их методы фабрики. Поскольку вы не можете построить объект с помощью new оператор от приватного внутреннего или пакет приватного типа из их объема (отражения в сторону.)

например:

 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(){}
    }
 }

скажем, у вас есть интерфейс под названием 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 - это интерфейс.


так возьмите, например сборники.unmodifiableList(...). Он возвращает некоторую реализацию List. Но имя класса реализации не имеет значения. Кроме того, указанный класс только построен через статический метод фабрики.


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

Foo foo = Foo.Factory.create();

1) я не понимаю ваш вопрос. Collection интерфейс и Collections имеет некоторые заводские методы, такие как emptyList

2) например экземпляр списка, возвращаемого Collection.emptyList является экземпляром частного класса, который реализует List интерфейс.


Это просто означает, что тип возвращаемого статические методы фабрики в Collections (и другие подобные классы) являются типами интерфейса (например,List), а не конкретные классы реализации (например,java.util.Collections.UnmodifiableList), которые не видны пользователям, так как это только усложнит ситуацию и увеличит размер API.