Когда использовать getInstanceOf вместо конструктора - PullRequest
3 голосов
/ 04 февраля 2010

Еще пару месяцев назад я посетил презентацию, организованную двумя представителями независимой компании по разработке программного обеспечения. В основном речь шла о хорошем дизайне программного обеспечения и практике.

Два парня говорили в основном о Java, и я помню, как они говорили, что в некоторых случаях очень полезно использовать getInstanceOf () вместо конструктора. Это было как-то связано с тем, чтобы всегда вызывать getInstanceOf () из разных классов, а не из конструктора, и как это было, гораздо лучше подходило для крупных проектов.

Как вы можете видеть, я не могу вспомнить из этого сейчас: / но я помню, что аргументы, которые они использовали, были действительно убедительными. Интересно, сталкивался ли кто-нибудь из вас с таким дизайном, и когда, по-вашему, он полезен? Или ты думаешь, что это совсем не так?

Ответы [ 4 ]

10 голосов
/ 04 февраля 2010
7 голосов
/ 04 февраля 2010

Они, вероятно, говорили о шаблоне статического метода фабрики (а не о методе API отражения для динамического создания объектов).

Существует несколько преимуществ метода, такого как getInstanceOf(), перед конструктором и использованием new.Статический метод фабрики может ...

  1. Выберите для создания другой подкласс основного класса, если это желательно в определенных случаях (на основе условий окружающей среды, таких как свойства и др.).объекты / синглеты или параметры метода).

  2. Выберите, чтобы вернуть существующий объект вместо его создания.Пример этого см. В Boolean.valueOf (логическое) в API Java.

  3. Сделайте то же самое, что и конструктор - просто верните новый экземплярсам класс.

  4. Предоставить много разных способов создания нового объекта и назвать эти методы так, чтобы они были менее запутанными (например, попробуйте это с конструкторами, и у вас скоро будет много разных перегрузок),Иногда это даже невозможно с помощью конструкторов, если вам нужно иметь возможность создавать экземпляр двумя разными способами, но нужно только один и тот же тип параметров.Пример:

    // This class will not compile!
    public class MyClass {
        public MyClass(String name, int max) {
            //init here
        }
        public MyClass(String name, int age) {
            // init here
        }
    }
    
    // This class will compile.
    public class MyClass2 {
        private MyClass2() {
        }
        public static MyClass2 getInstanceOfMax(String name, int max) {
            MyClass2 m2 = new MyClass2();
            // init here
            return m2;
        }
        public static MyClass2 getInstanceOfAge(String name, int age) {
            MyClass2 m2 = new MyClass2();
            // init here
            return m2;
        }
    }
    
  5. Делайте любую комбинацию из вышеперечисленного.

  6. И, помимо всего прочего, он скрывает детали созданияэкземпляр из других классов и, следовательно, может быть изменен в будущем (инкапсуляция конструкции).

Конструктор может только когда-либо создать новый экземпляр объекта с точным запрошенным типом.Его нельзя изменить позже.

Некоторые недостатки этого шаблона:

  1. Методы фабрики являются статическими, поэтому не могут наследоваться в подклассах;родительский конструктор легко доступен для подклассов.

  2. Имена фабричных методов могут широко варьироваться, и это может вводить в заблуждение некоторых (новых) разработчиков.

Вы также спрашивали о личном опыте.Да, я часто использую оба шаблона.Для большинства классов конструктор, но когда есть гораздо более сложные потребности, тогда я использую статическую фабрику.Я также работаю над проектами на других языках (проприетарных, но похожих на Java), где эта форма конструкции обязательна.

1 голос
/ 04 февраля 2010

Если Дрю прав, newInstance() является частью Java Reflection API. Так что это не так естественно, как использование конструктора.

Почему рекомендуется использовать его в большом проекте, может быть связано с тем, что он приводит к стилю программирования Java Bean и явно делает создание объекта чем-то конкретным. В крупном проекте создание объекта должно быть не сквозной задачей, а четко определенной ответственностью, часто из одного источника / фабрики. Но ИМХО, вы получаете все эти преимущества и многое другое с IoC pattern .

1 голос
/ 04 февраля 2010

Я подозреваю, что вы имеете в виду newInstance метод в классе Class. Вы бы назвали это так: MyClass foo = MyClass.newInstance();

Эта форма создания объектов популярна в шаблонах создания ; это полезно, когда вы хотите указать конкретный тип времени выполнения объекта извне , например, в свойствах или файле XML.

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