Использовать Enum или String для статического фабричного метода?

#java #enums #design-patterns #factory #static-factory

#java #перечисления #шаблоны проектирования #фабрика #статический завод

Вопрос:

Что лучше использовать enum или String отправлять в нужный объект для создания в static фабричном методе?

Пример с String :

 public static Car createCar(String carName){
    if(carName.equals("Ferrari")){
        return new Ferrari();
    }
    else if(carName.equals("Porsche")){
        return new Porsche();
    }
    ....
}
  

Пример с enum :

 public static Car createCar(CarEnum carEnum){
    if(CarEnum.FERRARI.equals(carEnum)){
        return new Ferrari();
    }
    else if(CarEnum.PORSCHE.equals(carEnum)){
        return new Porsche();
    }
    ....
}
  

На данный момент, по моему мнению :

Преимущества использования enum :

  • Избегайте того, чтобы пользователь вызывал фабрику с необработанным carName .

Недостаток использования Enum :

Увеличьте зависимости, потому что изменение в enum ( FERRARI ENZO_FERRARI например, становление) потребует модификации на клиенте. Однако с String помощью мы могли бы перенаправить Ferrari на Enzo Ferrari экземпляр без перекомпиляции клиентского кода. Конечно, мы могли бы сделать то же самое для клиента, используя старые enum значения с перенаправлением FERRARI на ENZO-FERRARI enum , но для меня это означает, что enum для обеспечения совместимости с клиентом необходимо сохранить старые значения… для меня это не имеет смысла.

Я хотел бы знать, каковы ваши мнения по этому вопросу?

Ответ №1:

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

Однако вы также можете рассмотреть, в ограниченном случае, подобном этому, использование именованных фабричных методов для каждого типа car: например, createFerrari() , createPorsche() и т. Д.

Комментарии:

1. Я предпочитаю это объяснение 🙂 Спасибо вам и спасибо другим, которые также хорошо ответили.

Ответ №2:

Ни то, ни другое. Используйте Enum и сделайте метод методом экземпляра самого Enum. Никаких if не требуется.

Комментарии:

1. @HosamAly Я не понимаю. При таком подходе фабрика уже абстрактна в базе Enum или, по крайней мере, может быть.

2. @EJP, не могли бы вы, пожалуйста, предоставить код для вашего ответа?

Ответ №3:

Я бы использовал Enums ; Мне не нравятся строки, используемые в этом случае. Преимущество перечислений в том, что вы можете переключаться между ними (что не будет работать со строками), и вам не нужно обрабатывать ложный ввод.

Ответ №4:

Я бы не стал добавлять методы экземпляра в перечисления. Сегодня мы увидели странное неожиданное поведение при использовании статических блоков в перечислениях и ссылках на перечисления. Внезапно экземпляр enum был нулевым !!!???
Я бы использовал абстрактный фабричный шаблон. Таким образом, вы могли бы использовать одну и ту же фабрику для двух экземпляров enum.
Я бы также использовал hashmap для хранения фабрик. Таким образом, у вас нет case или if, которые добавляют циклическую сложность.

Ответ №5:

Еще одним преимуществом enum является то, что он позволяет использовать switch/case синтаксис вместо бесконечного if/else .

Комментарии:

1. Да, но теперь с Java 7 мы можем переключаться с помощью String 😉