Эффективная Java от Джошуа Блоха: Item1 - Static Factory Method - PullRequest
22 голосов
/ 25 мая 2011

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

Цитата [Bloch, p.7]

Интерфейсы не могут иметь статические методы, поэтому по соглашению статические фабричные методы для интерфейса с именем Type помещаются внеинстанцируемый класс с именем Types.Например, Java Collections Framework, предоставляет неизменяемые коллекции, синхронизированные коллекции и тому подобное.Почти все эти реализации экспортируются через статические фабричные методы в один нереализуемый класс (java.util.Collections).Все классы возвращаемых объектов не являются общедоступными.

ОК.При взгляде на исходный код я вижу интерфейс java.util.Collection и класс java.util.Collections с закрытым конструктором (неинстанцируемый класс).и я вижу, что неинстанцируемый класс 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 ]

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

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

  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(){}
    }
 }
4 голосов
/ 25 мая 2011

Допустим, у вас есть интерфейс с именем 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 голосов
/ 26 мая 2011
public interface Foo
    static public class Factory
        public Foo create(){..}

Foo foo = Foo.Factory.create();
2 голосов
/ 25 мая 2011

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

1 голос
/ 25 мая 2011

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

1 голос
/ 25 мая 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...