一、抽象工厂模式
在工厂方法中, 所创建的汽车都是没有品牌的汽车. 现在假设, 车子有品牌了, 并且不止只有汽车, 还有自行车的生产. 那么可以把汽车和自行车做成两个抽象产品, 代码如下:
public abstract class NormalCar { public abstract void Start(); } public abstract class Bike { public abstract void Run(); }
为什么要把产品做成抽象的呢, 因为虽然各品牌的产品大体相同, 但是其中很多细节还是不一样的. 所以就产生了两种抽象产品, 汽车和自行车.
接下来就是各品牌自己的产品了, 此处假设品牌为 长城和哈弗, 代码如下:
public class ChangChengNormal : NormalCar { public override void Start() { Console.WriteLine("长城汽车, 钥匙启动"); } } public class ChangChengBike : Bike { public override void Run() { Console.WriteLine("长城自行车, 两只脚登"); } } //------------------------------------------------------------- public class HaFuNormal : NormalCar { public override void Start() { Console.WriteLine("哈弗汽车, 无钥匙启动"); } } public class HaFuBike : Bike { public override void Run() { Console.WriteLine("哈弗自行车, 电动辅助"); } }
从产品这边来看, 长城,哈弗都生产自行车和汽车, 并且各自生产的还有些不同, 或者是形状不同, 或者是价格不同, 又或者是功能不同. 等等.
产品设计已完成, 接下来要投入到厂房生产. 各品牌的车, 肯定不是在同一个厂生产出来, 提取他们共同部分, 形成一个厂的抽象类. 就是抽象工厂了, 代码如下:
public abstract class AbstractCarFactory { public abstract NormalCar CreateNormal(); public abstract Bike CreateBike(); }
在一个品牌的工厂中, 既要生产汽车, 也要生产自行车, 当然可能不是同一个厂房出来的, 这里并不关注这个, 而且, 抽象工厂生产的, 是一个产品族, 而不是一个个品牌.
既然抽象工厂已经出现, 那么各品牌就可以按照这个工厂模板去建立自己的工厂了, 自己的东西, 咱要自己造.
public class ChangChengFactory : AbstractCarFactory { public override NormalCar CreateNormal() { return new ChangChengNormal(); } public override Bike CreateBike() { return new ChangChengBike(); } } public class HaFuFactory : AbstractCarFactory { public override NormalCar CreateNormal() { return new HaFuNormal(); } public override Bike CreateBike() { return new HaFuBike(); } }
做到这里, 抽象工厂就基本完成了, 接下来, 我们来生产一辆汽车和一辆自行车:
AbstractCarFactory abFac = new ChangChengFactory(); NormalCar normal = abFac.CreateNormal(); Bike suv = abFac.CreateBike(); normal.Start(); suv.Run();
类图:
二、用简单工厂来修改抽象工厂
很多时候不需要这么复杂的过程, 如果项目为定制化的, 并非一个产品, 不需要那么强的扩展性, 也可以使用以下的方式:
public class CarFac { public static NormalCar CreateNormal(string brand) { switch (brand) { case "ChangCheng": return new ChangChengNormal(); case "HaFu": return new HaFuNormal(); default: return new ChangChengNormal(); } } public static Bike CreateBike(string brand) { switch (brand) { case "ChangCheng": return new ChangChengBike(); case "HaFu": return new HaFuBike(); default: return new ChangChengBike(); } } }
在工厂内部根据参数自行判断生产那种品牌的产品.
以上的方式, 当然还可以加入配置文件和反射来增加其扩展行, 思路与之前工厂模式的相同, 就不过多介绍了.
三、个人理解
工厂方法模式, 我觉得有点像是创建一条进程, 至于进程中是什么样的, 并不关注. 就像从深圳去上海, 可以选择坐飞机, 火车, 甚至轮船.
而抽象工厂, 感觉像是创建预期的进程, 进程中已经规划好了要创建的线程, 包括这些线程是做什么用的.
参考:
大话设计模式