看一个手机的简单实例来说明:(2015年11月2日增添内容)
看Java demo:
根据图的说明,我们来创建5个类来形象表示:
手机接口类:
public interface Phone { // 开的方法 public void turnOn(); // 关的方法 public void turnOff(); }iPhone,sumSung具体类,实现于Phone接口
public class iPhone implements Phone { public void turnOn() { // TODO Auto-generated method stub System.out.println("iPhone.turnOn()"); } public void turnOff() { // TODO Auto-generated method stub System.out.println("iPhone.turnOff()"); } } public class sumSung implements Phone { public void turnOn() { // TODO Auto-generated method stub System.out.println("sumSung.turnOn()"); } public void turnOff() { // TODO Auto-generated method stub System.out.println("sumSung.turnOff()"); } }手机工厂类,关联两类手机:
/** * * @ClassName: 采用工厂将产品创建的细节隐藏(产品发生改变,对客户端无影响) * @Description: TODO * @author: HuoYaJing * @date:2015年11月2日 下午2:22:04 */ public class PhoneFactory { // 创建两个静态变量,避免出错,方便调用 public static final String IPHONE="苹果手机"; public static final String SUMSUNG="三星手机"; public static Phone crewtePhone(String type){ // 通过传送类型来进行判断 Phone phone=null; if(IPHONE.equals(type)){ // …………………… phone=new iPhone(); }else if(SUMSUNG.equals(type)){ // …………………… Phone phone2=new sumSung(); }else{ // 抛出异常,无法生产 throw new RuntimeException("无法生产!"); } return phone; } }最后一个客户端调用:
public static void main(String[] args) { // 在工厂类中已经声明了静态方法,所以可直接调用,进行判断 // 苹果手机调用 // Phone phone = PhoneFactory.crewtePhone(PhoneFactory.IPHONE); // phone.turnOn(); // 三星手机调用 Phone phone = PhoneFactory.crewtePhone(PhoneFactory.SUMSUNG); phone.turnOn(); }
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
最大的特点就是针对每一个对象建造一个工厂。同时这也是这个模式的缺点。由于每加一个产品,就要增加一个产品工厂的类,这样无疑就增加了额外的开发量。
Java demo:
相比简单工厂,我们需要将工厂改为接口类,创建单独的两个工厂去实现想要的需求。
PhoneFactory:
/** * * @ClassName: 采用工厂将产品创建的细节隐藏(产品发生改变,对客户端无影响) * @Description: TODO * @author: HuoYaJing * @date:2015年11月2日 下午2:22:04 */ public interface PhoneFactory { // 只需要一个创建的方法则行 public Phone crewtePhone(); }两个工厂方法:
public class iPhoneFactory implements PhoneFactory { @Override public Phone crewtePhone() { // TODO Auto-generated method stub // 制造苹果手机方法,省略 // ………………………… return new iPhone(); } } public class sumSungFactory implements PhoneFactory { @Override public Phone crewtePhone() { // TODO Auto-generated method stub // 制造三星手机方法,省略 // ………………………… return new sumSung(); } }
那么优点是什么呢? 其实相比于上一个简单工厂来说,其实主要的变化就是将其工厂分类,各自生产各自的,目的是什么,是为了增添新的手机生产而对原有的不受影响,比如我再增加一个乐视手机,那么照之前的方式来说我必须得改变原有的工厂里边的方法才能满足需求,但是如果使用工厂方法来完成,则直接再新增一个工厂来为其服务就好,这就是工厂方法。
工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂模式是工厂方法模式的升级版,他用来创建一组相关或者相互依赖的对象。下边用具体的例子来描述一下。前阵子去北京回来的路上,遇见一个东北的大叔要去富士康打工,自己还好心给了个公交钱指路。
对于富士康,相信大家不会陌生——一个生产计算机,电子产品的企业。现在要给两个品牌做代工产品:三星和苹果,这两个品牌都有手机和电脑。由于生产工艺的不同,开设了两条生产线:一条线只生产手机,一条线只生产电脑,总负责人是老王。假设现在我要一部三星手机,那么老王则对着电脑说,生产一部三星手机;某一天我又想要一个苹果电脑,那么老王又对着生产电脑的生产线,输入:生产一台苹果电脑……
构件图:
这个例子中主要涉及到了两种抽象产品(三星和苹果),而每种抽象的产品都有两种产品角色(手机和电脑),这样就要建立两种工厂(手机工厂和电脑工厂)分别负责不同产品角色的实例化。而老王就是那个工厂的总接口,负责找到正确的生产工厂,并且拿到你想要的类型的产品。
这就是所谓的抽象工厂模式,每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式针对的是多个产品等级结构。有多少个产品等级结构,就会在工厂角色中发现多少个工厂方法。
好处说完了,当然也存在着自身的缺点了,抽象工厂最大的缺点就是对产品族的扩展非常困难。这时候就需要简单工厂小妹来帮忙了,舍弃该舍弃的类。
其实工厂三姐妹各有各的优缺点,简单工厂就是只有一个具体工厂类来创建一种基类的多个不同的派生类;工厂方法就是有多个派生于一个基类的具体工厂类,每个具体工厂只生产一种基类的一个派生类;抽象工厂也是只有一个工厂基类,但是每个具体工厂生产多个相关基类的各一个派生类,就如上产三星手机一样。
再换句话而言,其实就如上例中,简单工厂就是一条生产线,不管你生产什么,是电脑还是手机,都只是在这条生产线上生产,而工厂方法则是由于生产的多了,老板突然发现就一条生产线效率太低了,所以就多开发了一条,一条用来生产手机,一条用来生产电脑,这样就大大的提高了其生产效率。而抽象工厂则是将老板的整个工厂再复制一份,用来生产不同品牌的电脑和手机。