工厂模式:
工厂模式可以分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
简单工厂模式
插头 分为二孔插头和三孔插头。
首先 创建插头产品类 Pin
public class Pin { protected String PinType; }
然后分别创建二孔插头和三孔插头类
/** * @author hjn *二孔插头类 */ public class PinTw extends Pin { private String PinType; public String getPinType() { return PinType; } public void setPinType(String pinType) { PinType = pinType; } public PinTw() { System.out.println("I am 2孔 Pin"); } } /** * @author hjn *三孔插头类 */ public class PinTh extends Pin { private String PinType; public String getPinType() { return PinType; }
public void setPinType(String pinType) { PinType = pinType; } public PinTh() { System.out.println("I am 3孔 Pin"); } }
然后创建插头工厂类
/** * @author hjn *插头工厂类 */ public class PinFactory { /** * @param type * @return * 根据插头数返回相对的插头对象 */ public static Pin creatPin(int type) { switch (type) { case 2: return new PinTw(); case 3: return new PinTh(); default: break; } return null; } }
最后 测试类 :
public class TestPin { public static void main(String[] args) { Pin pinth = PinFactory.creatPin(3); Pin pintw = PinFactory.creatPin(2); } }
这就是简单工厂模式。
简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。
先来看看它的组成:
1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在Java中由一个具体类实现。
下面我们从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式。当客户不再满足现有的插头型号的时候,想要一种更多头的新型插头,只要这种插头符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一种新型插头,都要在工厂类中增加相应的创建业务逻辑(creatPin(int type)方法需要新增case),这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的。对于这样的工厂类,我们称它为全能类或者上帝类。
我们举的例子是最简单的情况,而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝累坏了,也累坏了我们这些程序员。
于是工厂方法模式作为救世主出现了。 工厂类定义成了接口,而每新增的插头种类型,就增加该插头种类型对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码。
简单工厂模式的优缺点
优点:客户端不需要修改代码。
缺点: 当需要增加新的运算类的时候,不仅需新加运算类,还要修改工厂类,违反了开闭原则。
工厂方法模式
工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
工厂方法模式组成:
1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的!
首先 创建插头产品类 Pin
public class Pin { protected String PinType; }
然后分别创建二孔插头和三孔插头类
/** * @author hjn *二孔插头类 */ public class PinTw extends Pin { private String PinType; public String getPinType() { return PinType; } public void setPinType(String pinType) { PinType = pinType; } public PinTw() { System.out.println("I am 2孔 Pin"); } } /** * @author hjn *三孔插头类 */ public class PinTh extends Pin { private String PinType; public String getPinType() { return PinType; } public void setPinType(String pinType) { PinType = pinType; } public PinTh() { System.out.println("I am 3孔 Pin"); } }
然后创建插头工厂接口:
/** * @author hjn * 工厂方法接口* */ public interface IPinFactory { public Pin creatPin(); }
然后创建 二孔插头和三孔插头的工厂
/** * @author hjn *二孔的工厂类 */ public class PinTwFactory implements IPinFactory { Pin ptw=new PinTw(); public Pin creatPin() { return ptw; } } /** * @author hjn *三孔的工厂类 */ public class PinThFactory implements IPinFactory { Pin pth=new PinTh(); public Pin creatPin() { return pth; } }
测试类 :
public class TestPin { public static void main(String[] args) { PinThFactory pthf =new PinThFactory(); Pin pinth = pthf.creatPin(); PinTwFactory ptwf=new PinTwFactory(); Pin pintw = ptwf.creatPin(); } }
这个和简单工厂有区别,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂,当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。
好处:增加一个运算类(例如N次方类),只需要增加运算类和相对应的工厂,两个类,不需要修改工厂类。
缺点:增加运算类,会修改客户端代码,工厂方法只是把简单工厂的内部逻辑判断移到了客户端进行。
抽象工厂模式
首先 创建插头产品类 Pin
public class Pin { protected String PinType; }
然后分别创建二孔插头和三孔插头类
/** * @author hjn *二孔插头类 */ public class PinTw extends Pin { private String PinType; public String getPinType() { return PinType; } public void setPinType(String pinType) { PinType = pinType; } public PinTw() { System.out.println("I am 2孔 Pin"); } }
/** * @author hjn *三孔插头类 */ public class PinTh extends Pin { private String PinType; public String getPinType() { return PinType; } public void setPinType(String pinType) { PinType = pinType; } public PinTh() { System.out.println("I am 3孔 Pin"); } }
然后创建插头工厂接口:
/** * @author hjn * 工厂方法接口* */ public interface IPinFactory { public Pin creatPinTw(); public Pin creatPinTh(); } /** * @author hjn *Pin工厂实现类 */ public class PinFactoryImpl implements IPinFactory { @Override public Pin creatPinTw() { return new PinTw(); } @Override public Pin creatPinTh() { return new PinTh(); } }
测试类
public class TestPin { public static void main(String[] args) { PinFactoryImpl pin = new PinFactoryImpl(); Pin ptw = pin.creatPinTw(); Pin pth = pin.creatPinTh(); } }
抽象工厂模式,一个具体工厂可以制造几个产品
优点:易于交换产品系列,例如Access和SQLServer数据库之间切换。
缺点:如果需要增加新的产品树,那么就要新增三个产品类,并且要修改三个工厂类。这样大批量的改动是很丑陋的做法。
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。