在简单工厂模式中实现了对产品类的开闭原则,但是对于工厂类而言却是不符合软件设计的开闭原则。工厂模式正是可以解决这个问题。在简单工厂模式中,我们定义了三个角色,工厂类,抽象产品类和产品类。其中产品类继承了抽象产品类,在工厂类存在一个抽象产品类的引用和一个静态方法来根据用户传入的业务逻辑创建对应的产品类。当产品类越来越多时,可以想象工厂类的静态方法的代码就会越来越来多,所以在工厂模式中我们将引入一个抽象工厂类,这样每产生一个产品就会有一个与之对应的工厂类,原来在简单工厂模式中的工厂就会被继承自抽象工厂的对个子类索替代。
下面是用java代码实现的工厂模式。表示抽象的工厂角色。
public interface CpuFactory { public Cpu getCpu(); }
表示抽象的产品角色。
public interface Cpu { public void run(); }
表示具体的产品角色和具体的工厂角色
public class AmericaCpu implements Cpu{ @Override public void run() { System.out.println("运行美国cpu"); } }
public class AmericanCpuFactory implements CpuFactory{ public Cpu getCpu(){ return new AmericaCpu(); } }
当用户调用时
public static void main(String[] args) { CpuFactory factory = new AmericanCpuFactory(); Cpu cpu = factory.getCpu(); cpu.run(); }
可以看出工厂方法的加入使得类的数量大幅的增加,工厂模式虽然符合了软件设计的原则但是我为此付出了一定的代价。所以在实际开发中我们要把简单工厂模与工厂模式结合在一起使用。可以考虑是否可以把产品按类型分,不是每一个产品类就对应一个工厂类
而是每一类产品对应一个工厂类。
工厂模式的使用场景:(1)当客户程序不需要知道要使用对象的创建过程 (2)客户程序使用的对象存在变动,或者根本不知道该使用哪一个具体的对象。
小结:简单的工厂模式和工厂模式并没有真正的避免对代码的改动,在简单工厂模式是当加入新的产品时需要修改创建产品的静态方法;在工厂模式中需要用户知道具体产品对应的工厂类。当创建产品的条件改变势必导致工厂类代码的修改。面对这种情况java的反射机制和配置文件可以解决这个问题。这一点在spring框架中得到了验证。