工厂设计模式

来源:互联网 发布:蔡珍妮淘宝退货地址 编辑:程序博客网 时间:2024/06/06 06:42

工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。

工厂模式的几种形态:

1、简单工厂(Simple Factory)

2、工厂方法(Factory method)

3、抽象工厂(Abstract Factory)


简单工厂(Simple Factory)

简单工厂又称为静态工厂,主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。

情景:一家工厂生产洗衣机、空调、冰箱三种产品。


首先为所有的产品定义一个共同的产品接口:

public interface Product {}
<span style="font-family:KaiTi_GB2312;font-size:14px;">让所有产品都实现该接口:</span>
/** * 洗衣机 */public class Washer implements Product{public Washer() {System.out.println("洗衣机被制造了");}}/** * 冰箱 */public class Icebox implements Product{public Icebox() {System.out.println("冰箱被制造了");}}/** * 空调 */public class AirCondition implements Product{public AirCondition() {System.out.println("空调被制造了");}}


接下来定义一个工厂类负责生产这些产品:

public class SimpleFactory {public static Product create(String productName) throws Exception{Product product = null;if("washer".equals(productName)){product = new Washer();}else if("airCondition".equals(productName)){product = new AirCondition();}else if("icebox".equals(productName)){product = new Icebox();}else{throw new Exception("没有该产品");}return product;}}


最后测试类,根据传入的参数来决定生产什么类型的产品:

/** * 简单工厂又称静态工厂(Simple Factory)测试类 */public class Test {public static void main(String[] args) {try {//生产冰箱SimpleFactory.create("icebox");//生产空调SimpleFactory.create("airCondition");//生产洗衣机SimpleFactory.create("washer");//生产没有的产品,抛出异常SimpleFactory.create("cellPhone");} catch (Exception e) {e.printStackTrace();}}}


由上可以看出简单工厂的核心是SimpleFactory类,该类必须具有逻辑判断能力和所有产品的生产权利,我们只需要将订单给他,我们就能获得相对应的产品,这看似十分方便,但却很多的局限性,比如当我们每次想要生产一个新产品时都必须修改SimpleFactory的原代码。其次,当我们拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这对以后的维护简直就是恐怖两个字...
还有就是,整个系统都严重依赖SimpleFactory类,只要SimpleFactory类一出问题,系统就进入不能工作的状态,这也是最为致命的一点....
以上的不足将在工厂模式的另外两种状态中得到解决。


工厂方法(Factory Method)

上面的代码告诉我们,简单工厂并不简单,它是整个模式的核心,一旦他出了问题,整个模式都将受影响而不能工作,为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,引入工厂方法
工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能,以下是工厂接口的定义:

/** * 工厂接口 */public interface Factory {/** * 创建产品 * @return 产品 */public Product create();}/** * 产品接口 */public interface Product {}
</pre><pre code_snippet_id="1660692" snippet_file_name="blog_20160425_6_3900036" name="code" class="java"><span style="font-family:KaiTi_GB2312;font-size:14px;">以下是实现了产品接口的产品类:</span>
</pre><pre code_snippet_id="1660692" snippet_file_name="blog_20160425_8_9690321" name="code" class="java">/** * 空调 */public class AirCondition implements Product{public AirCondition(){System.out.println("空调被制造了");}}/** * 冰箱 */public class Icebox implements Product{public Icebox(){System.out.println("冰箱被制造了");}}/** * 洗衣机 */public class Washer implements Product{public Washer(){System.out.println("洗衣机被制造了");}}


接下来就产品的核心类,也就创建产品的工厂类:

/** * 空调生产工厂 */public class AirConditionFactory implements Factory{@Overridepublic Product create() {return new AirCondition();}}/** * 冰箱生产工厂 */public class IceboxFactory implements Factory{@Overridepublic Product create() {return new Icebox();}}/** * 洗衣机生产工厂 */public class WasherFactory implements Factory{@Overridepublic Product create() {return new Washer();}}

测试类:

/** * 工厂方法(Factory Method)测试类 */public class Test {public static void main(String[] args) {//调用洗衣机生产工厂,生产洗衣机Factory washerFactory = new WasherFactory();Washer washer = (Washer) washerFactory.create();//调用空调生产工厂,生产空调Factory airConditionFactory = new AirConditionFactory();AirCondition airCondition = (AirCondition) airConditionFactory.create();//调用冰箱生产工厂,生产冰箱Factory iceboxFactory = new IceboxFactory();Icebox icebox = (Icebox) iceboxFactory.create();}}

从上面创建产品对象的代码可以看出,工厂方法简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难.....


抽象工厂(Abstract Factory)

抽象工厂是在生产产品的同时对产品进行分类处理,比如说“冰箱A、冰箱B、洗衣机A、洗衣机B”这四种产品,可以将“冰箱A、洗衣机A”两种A类产品归为一类,“冰箱B、洗衣机B”两种B类产品又归为一类:

首先为冰箱和洗衣机两种产品分别定义一个产品接口:

/** * 冰箱接口 */public interface Icebox {}/** * 洗衣机接口 */public interface Washer {}


接着分别创建这两个接口的具体产品:

/** * 冰箱A */public class IceboxA implements Icebox{public IceboxA() {System.out.println("冰箱A被制造了");}}/** * 冰箱B */public class IceboxB implements Icebox{public IceboxB() {System.out.println("冰箱B被制造了");}}/** * 洗衣机A */public class WasherA implements Washer{public WasherA() {System.out.println("洗衣机A被制造了");}}/** * 洗衣机B */public class WasherB implements Washer{public WasherB() {System.out.println("冰箱B被制造了");}}

到此,产品部分准备完毕,接下来我们来定义一个产品工厂接口:

/** * 工厂接口 */public interface Factory {public Washer createWasher();public Icebox createIcebox();}

然后创建工厂类实现工厂:

/** * 生产A类产品的工厂 */public class FactoryA implements Factory{@Overridepublic Washer createWasher() {return new WasherA();}@Overridepublic Icebox createIcebox() {return new IceboxA();}}/** * 生产B类产品的工厂 */public class FactoryB implements Factory{@Overridepublic Washer createWasher() {return new WasherB();}@Overridepublic Icebox createIcebox() {return new IceboxB();}}


测试类:
/** * 抽象工厂(Abstract Factory)测试类 */public class Test {public static void main(String[] args) {//调用A类工厂,生产A类冰箱和A类洗衣机Factory factoryA = new FactoryA();IceboxA iceboxA = (IceboxA) factoryA.createIcebox();WasherA washerA = (WasherA) factoryA.createWasher();//调用B类工厂,生产B类冰箱和B类洗衣机Factory factoryB = new FactoryB();IceboxB iceboxB = (IceboxB) factoryB.createIcebox();WasherB washerB = (WasherB) factoryB.createWasher();}}











0 0