标签:
A、介绍
在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?提供一种封装机制来隔离出“这个易变对象”的变化,从而保持系统中“其它依赖该对象的对象”不随着需求的改变而改变?这就是要说的Factory Method模式了。
顾名思义,建立一个接口(抽象工厂类),继承此接口的子类们(具体工厂类),可以各自相应生产出各种不同的产品类实例(具体产品),即接口不直接生产具体产品类,而是让继承它的子类去决定实例化哪一个类,使一个类的实例化延迟到其子类。
B、意义
定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。
当新增加具体产品类时,不需要更改。
一句话:创建一组可以“生产产品类”的类。如:要创建“红色四轮”汽车类、“蓝色三轮”汽车类、“粉色二轮”汽车类,只需创建一个带“颜色、轮数”参数的工厂,分别new出三个汽车类,三个汽车类再分别new出三种汽车实例。
目的:用于生成“多种”不同类型的对象。
区别:
1.与建造者模式区别:建造者模式是将需要“一系列复杂”的多个类的构建过程,封装成一个“集成”类,即将一个复杂对象的构造与它的表示分离,侧重于“整合多个操作”。
2.与门面模式区别:门面模式是将多个接口整合成一个接口,侧重于“整合多个接口”。
C、结构
工厂模式主要是为创建对象提供了接口。工厂模式分为三类:
简单工厂:一个工厂生产多个产品
工厂方法:基工厂有多个子工厂,每个子工厂可以生产一个产品
抽象方法:基工厂有多个子工厂,每个子工厂可以生产多个产品
I.简单工厂模式(Simple Factory)
SimpleFactory
|实
|例
|化
Production : ProductionA、ProductionB、...
Production productionA = SimpleFactory.GenerateProduction("ProductionA");
Production productionB = SimpleFactory.GenerateProduction("ProductionB");
1.工厂层:工厂类
2.产品层:
2.1 抽象产品层:抽象产品接口
2.2 具体产品层:具体产品类
3.调用层:产品A 我的产品 = 静态工厂类.GenerateProduction("产品A")
II. 工厂方法模式(Factory Method)
IFactory : FactoryA、FactoryB、...
|实
|例
|化
Production : ProductionA、ProductionB、...
IFactory FactoryA = new FactoryA();
IFactory FactoryB = new FactoryB();
Production productionA = FactoryA.GenerateProduction();
Production productionB = FactoryB.GenerateProduction();
1.工厂层:
1.1 抽象工厂层:抽象工厂接口
1.2 具体工厂层:具体工厂类
2.产品层:
2.1 抽象产品层:抽象产品接口
2.2 具体产品层:具体产品类
3.调用层:工厂接口
工厂接口 工厂 = new 工厂子类(产品类);
产品类 产品 = 工厂.生产();
III. 抽象工厂模式(Abstract Factory)
IFactory : FactoryA、FactoryB、...
|实
|例
|化
Production : ProdA1、ProdA2、ProdA3、ProdB1、ProdB2、...
同“工厂方法”模式,只不过工厂层中的每个工厂是包含多个产品生产方法。
D、实例
本例的主线:Driver(工厂)->Car(产品)
I、简单工厂(Simple Factory)
如需增加产品需要更改产品类
--产品A
产品类--|
--产品B
例:
//产品层 //抽象产品接口 public interface ICar{ void launch(); } //具体产品类 public Benz implements ICar{ public void launch() { System.out.println("Driving Benz"); } } public Bmw implements ICar{ public void launch() { System.out.println("Driving Bmw"); } } //工厂层 //工厂类(核心部分) public class Driver{ public static ICar DistributeCar(String s) throws Exception{ if(s.equalsIgnoreCase("Benz")) return new Benz(); else if(s.equalsIgnoreCase("Bmw")) return new Bmw(); ... else throw new Exception(); } } //调用层 //调用类 public class Program{ public static void main(String[] args) { ICar car = Driver.DistributeCar("Benz"); car.launch(); } }
弊端:需要一个全能类(或者叫上帝类),本例中是Driver。
II、工厂方法(Factory Method)
增加产品不需要更改工厂类,只需要在定义新工厂类时添加一个实现
一个工厂基类被多个工厂类实现,一个工厂类只可以生产一个产品
--工厂A--产品A
工厂基类--|
--工厂B--产品B
例:
//产品层 //抽象产品接口 同上 //具体产品类 同上 //工厂层 //抽象工厂接口(核心部分) public interface Driver{ ICar DistributeCar(); } //具体工厂类 public class BenzDriver implements Driver{ public ICar DistributeCar(){ return new Benz(); } } public class BmwDriver implements Driver{ public ICar DistributeCar(){ return new Bmw(); } } //调用层 //调用类 public class Program{ public static void main(String[] args){ Driver _benzDriver = new BenzDriver(); //工厂类 ICar car = _benzDriver.DistributeCar(); //(通过工厂类)得到产品类 car.launch(); } }
III、抽象工厂(Abstract Factory)
同样是一个工厂基类被多个工厂类实现,但一个工厂类可以生产“一个系列的多个产品”,如手机工厂可以生产屏幕、电池、摄像头、内存等。
--产品A1
--工厂A--|
| --产品A2
工厂基类--|
| --产品B1
--工厂B--|
--产品B2
例:
//产品层 //定义产品1抽象接口 interface ICar {...} //定义产品1具体类 class Benz : ICar {...} class Bmw : ICar {...} //定义产品2抽象接口 interface IWheel {...} //定义产品具体2类 class BenzWheel : IWheel {...} class BmwWheel : IWheel {...} //工厂层 //抽象工厂接口(核心部分) public interface Driver{ ICar DistributeCar(); IWheel DistributeWheel(); } //具体工厂类 public class BenzDriver implements Driver{ public ICar DistributeCar(){ return new Benz(); } public IWheel DistributeWheel(){ return new BenzWheel(); } } public class BmwDriver implements Driver{ public ICar DistributeCar(){ return new Bmw(); } public IWheel DistributeWheel(){ return new BmwWheel(); } } //调用层 //调用类 public class Program{ public static Main(String[] args){ //生产BenzWheel Driver benzDriver = new BenzDriver(); ICar BenzCar = benzDriver.DistributeCar(); IWheel BenzWheel = benzDriver.DistributeWheel(); } }
标签:
原文地址:http://www.cnblogs.com/zayu/p/5878048.html