Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Когда использовать getInstanceOf вместо конструктора

Автор вопроса: ArturОтветов: 4

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

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

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

  • Я не уверен, в каком контексте вы бы это использовали. Обычным является Class.forName (org.apache.derby.jdbc.EmbeddedDriver); для загрузки драйверов db stacker 04.02.2010
  • Не уверен, правильно ли думают другие респонденты. Вы действительно говорите об использовании фабричного метода в классе вместо прямого создания экземпляра с помощью 'new'? Или что-то другое? PSpeed 04.02.2010

javaconstructorsoftware-design

Ответы

Ответ 1 · рейтинг 8 · Kevin Brock

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

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

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

  2. Выберите возврат существующего объекта вместо его создания. Для примера см. Boolean.valueOf (boolean) в Java API.

  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), где эта форма построения обязательна.

Ответ 2 · рейтинг 10 · trashgod

Используйте статические фабричные методы вместо конструкторов - Джошуа Блох

Ответ 3 · рейтинг 1 · Drew Wills

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

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

Ответ 4 · рейтинг 1 · Hubert

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы