工厂模式动态方法

2022-09-03 17:04:53

我试图理解工厂模式。如果有很多实现,那么我的工厂模式将有很多如果其他或切换的情况。而且每次我引入新的实现时,我都应该更改我的工厂代码

就像在下面的例子中,如果让我们假设狗鸭子正在实现像明天一样的宠物接口,如果许多动物实现宠物接口,我的工厂长长,如果其他代码或开关案例。有没有办法通过引入更动态的方法来解决这个问题?

package com.javapapers.sample.designpattern.factorymethod;

//Factory method pattern implementation that instantiates objects based on logic
public class PetFactory {

    public Pet getPet(String petType) {
        Pet pet = null;

        // based on logic factory instantiates an object
        if ("bark".equals(petType))
            pet = new Dog();
        else if ("quack".equals(petType))
            pet = new Duck();
        return pet;
    }

如果动物生长

if ("bark".equals(petType))
    pet = new Dog();
else if ("quack".equals(petType))
    pet = new Duck();
else if ("mno".equals(petType))
    pet = new MNO();
else if ("jkl".equals(petType))
    pet = new JKL();
else if ("ghi".equals(petType))
    pet = new GHI();
else if ("def".equals(petType))
    pet = new DEF();
......
else if ("abc".equals(petType))
    pet = new ABC();
return pet

答案 1

我认为有一种动态的方法:

  1. 在您的工厂中,您需要一个Map<String, Class<? extends Pet>>
  2. 在每个类的静态构造函数中,扩展 Pet,将其注册到此类映射。
  3. 比创建一个类将只是(当然,你必须检查空值)map.get(pet).newInstance

答案 2

工厂模式背后的想法是让您动态实例化对象,这些对象的类型在设计时不一定知道。

有一个大块会破坏这个目的。if

实现此模式的有效方法是为每种类型的类型创建一个工厂,该工厂实现一个基本工厂接口,并能够实例化该类型的新对象(顺便说一句,在Java中,内置就是这种工厂的一个例子)。Class

然后,在运行时将名称/id/等的映射注册到这些单个工厂的实例。当需要实例化其中一种类型时,您可以按名称在映射中查找工厂,并使用它来实例化该类型的新对象。

如何在地图中注册单个工厂完全悬而未决。您可以显式注册一些,可以扫描配置文件等。

实质上,您希望将块替换为在运行时动态创建的映射。if

您甚至不需要仅使用预先注册的“map” - 有时可能适合弄清楚如何动态创建具有给定名称的对象,或者两者的组合(例如 如果找不到已加载的类,则搜索类路径)。关键是可以将名称转换为类类型,而无需基工厂实际知道类类型是什么。Class.forName()

值得注意的是,Java反射已经通过和/或提供了一个非常可行的工厂实现,所以如果它有意义,请考虑使用它而不是重新发明轮子。Class.forName()Class.newInstance()


推荐