设计模式

设计模式

一、抽象工厂模式

在工厂方法中, 所创建的汽车都是没有品牌的汽车. 现在假设, 车子有品牌了, 并且不止只有汽车, 还有自行车的生产. 那么可以把汽车和自行车做成两个抽象产品, 代码如下:

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();
        }
    }
}

在工厂内部根据参数自行判断生产那种品牌的产品.

以上的方式, 当然还可以加入配置文件和反射来增加其扩展行, 思路与之前工厂模式的相同, 就不过多介绍了.

三、个人理解

工厂方法模式, 我觉得有点像是创建一条进程, 至于进程中是什么样的, 并不关注. 就像从深圳去上海, 可以选择坐飞机, 火车, 甚至轮船.

而抽象工厂, 感觉像是创建预期的进程, 进程中已经规划好了要创建的线程, 包括这些线程是做什么用的. 

参考:

  Abstract Factory Pattern

  大话设计模式