链接地址:http://www.xx566.com/detail/134.html
上一篇,我们学习了简单工厂(Simple Factory)模式 , 它允许客户端相对独立于产品创建的过程,并且在系统引入新产品时无需修改客户端,但是却需要修改工厂类的代码,将必要的逻辑加入到工厂类,本篇即将学习的 工厂方法(Factory Method)模式旨在解决这个问题,利用面向对象的多态,对简单工厂模式进行进一步的抽象,接下来,我们开始工厂方法模式的学习。
首先,我们简单了解一下工厂方法模式(来自百度百科):定义一个创建产品对象的工厂借口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类称为一个抽象角色,仅负责具体工厂子类必须实现的接口。我们来看一下工厂方法模式的UML类图,如下:
上图中,我们可以看到,工厂方法模式包含以下四种角色,如下:
抽象工厂(Creator)角色:担任这个角色的是工厂方法模式的核心,它与应用程序无关,任何在模式中创建的对象的工厂类必须实现这个接口。
具体工厂(Concrete Creatot)角色:担任这个角色的是实现了抽象工厂接口的具体Java类,它主要包含与应用程序相关的具体逻辑,并且受到应用程序的调用来创建对象。
抽象产品(Product)角色:工厂方法模式所创建的产品对象的共同父类或共有接口。
具体产品(Concrete Product)角色:实现了抽象产品接口的具体产品类,它由具体的工厂类创建。
接下来,我们通过修改简单工厂(Simple Factory)模式中的代码实例,来学习工厂方法模式,不再像简单工厂模式中的Foxconn中具体的工厂那样,首先我们抽象出一个手机工厂,具有生产手机的方法,代码如下:
/** * 抽象出的手机工厂 * User: Realfighter * Date: 2014/8/25 * Time: 21:08 */ public interface MobileFactory { /** * 生产手机 * @return */ Mobile produce(); }
接下来,我们继续抽象,为每种手机抽象出一个Mobile接口,拥有自己的品牌和价格,代码如下:
/** * 抽象手机设备接口 * User: Realfighter * Date: 2014/8/25 * Time: 21:08 */ public interface Mobile { public String brand();//手机品牌 public double price();//手机价格 }
然后,我们需要为手机供应商提供各式各样具体的设备,如Nokia和Iphone,代码如下:
/** * Nokia手机实例 * User: Realfighter * Date: 2014/8/25 * Time: 21:08 */ public class Nokia implements Mobile { @Override public String brand() { return "Nokia"; } @Override public double price() { return 3000.0; } //这里为了方便调试,重写了toString @Override public String toString() { return this.brand() + ":" + this.price(); } } /** * Iphone手机实例 * User: Realfighter * Date: 2014/8/25 * Time: 21:08 */ public class Iphone implements Mobile { @Override public String brand() { return "Iphone"; } @Override public double price() { return 5000.0; } //这里为了方便调试,重写了toString @Override public String toString() { return this.brand() + ":" + this.price(); } }
有了抽象的手机工厂和具体的手机,我们需要具体的针对于每种手机创建自己的工厂,如:NokiaFactory和IphoneFactory ,对抽象工厂做了具体实现,代码如下:
/** * Nokia手机工厂 * User: Realfighter * Date: 2014/8/25 * Time: 21:09 */ public class NokiaFactory implements MobileFactory { @Override public Mobile produce() { return new Nokia(); } } /** * 苹果手机工厂 * User: Realfighter * Date: 2014/8/25 * Time: 21:08 */ public class IphoneFactory implements MobileFactory { @Override public Mobile produce() { return new Iphone(); } }
接下来,我们的手机供应商就需要和工厂合作,进行手机的销售了,代码如下:
/** * 手机供应商 * User: Realfighter * Date: 2014/8/23 * Time: 21:08 */ public class Supplier { public static void main(String[] args) { //首先找到Nokia手机工厂 MobileFactory factory = new NokiaFactory(); //Nokia工厂开始生产手机 Mobile mobile = factory.produce(); System.out.println(mobile.toString()); //Nokia:3000.0 //再找到Iphone手机工厂 factory = new IphoneFactory(); //Iphone工厂开始生产手机 mobile = factory.produce(); System.out.println(mobile.toString());//Iphone:5000.0 } }
总结:相对于简单工厂模式,工厂方法模式充分体现了面向对象多态性的特点,设计上做了更深层次的抽象,核心由一个具体类到一个抽象的工厂类,当系统中需要 加入新的产品,我们只需要加入一个产品类和它所对应的工厂类,不需要修改客户端代码,也不需要修改抽象工厂类和其它具体的工厂角色,能够很好的支持扩展, 完全符合设计模式“开闭”原则。