设计模式(6)抽象工厂

0参考

(1)https://www.jianshu.com/p/6060e0632071

(2)https://www.bilibili.com/video/BV1Jz4y1d7TX/?p=3

1、为什么使用工厂?

(1)在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。

(2)如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?

(3)提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。(《设计模式》GoF)

2、抽象工厂方式的图

(1)注意,下图中具体的产品A1和B1相互依赖(是一伙的,搭配的),A2和B2相互依赖(是一伙的,搭配的)

(2)客户程序只依赖于AbstractFactory、AbstractProductA和AbstractProductB三个抽象类。

(3)如果这个时候有新的类型的对象要添加,比如说要创建未来风格的A3和B3,这个时候只要添加新的工厂类就可以。(客户的依赖还是那3项,没有任何改变

3、抽象工厂的例子说明

3.1使用abstract还是interface

(1)abstract和interface的区别详见我的教程https://www.toutiao.com/article/7288888037336220223/

(2)接口相对来说更底层更抽象,abstract可以带更多自身具体的实现,根据需要看看要不要进一步抽象为interface。

(3)不管用abstract还是interface实现抽象工厂,思想是一样的。

3.2例子说明

(1)想了半天,想了个无聊的游戏例子,需要创建一个游戏对象,属性包括:武器,坐骑....它们会有很多组合,以后还可能添加很多其它的属性。

(2)这个例子的图我简单画了一下,如下所示

3.3代码的各模块定义

3.3.1抽象产品和抽象工厂的定义

(1)抽象武器类的定义,包含了2个方法名字和伤害(当然C#也可以用Abstract修饰属性)

//(1)抽象武器
public abstract class Weapon
{
        //名字
        public abstract void ShowName();
        //伤害
        public abstract void Damage();
}

(2)抽象坐骑类的定义,包含了2个方法物种和运动方式(当然C#也可以用Abstract修饰属性)

//(2)抽象坐骑
public abstract class Mount
{
    //物种
    public abstract void AnimalSpecies();
    //运动方式
    public abstract void MotionType();
}

(3)抽象角色工厂的定义,包括了创建武器和坐骑

//(3)抽象角色工厂
public abstract class CharacterFactory
{
    public abstract Weapon CreateWeapon();
    public abstract Mount CreateMount();
}

3.3.2具体产品的实现

(1)两个具体武器产品的实现例子

//(4.1)具体武器1,刀
public class TangKnife : Weapon
{
        //名字
        public override void ShowName()
        {
            Console.WriteLine("I'm a Big Tang Knife!!");
        }
        //伤害
        public override void Damage()
        {
            Console.WriteLine("Causing Great damage!");
        }
}
//(4.2)具体武器2,弓
public class HouyiBow : Weapon
{
        //名字
        public override void ShowName()
        {
            Console.WriteLine("I'm a Bow used by Houyi!!");
        }
        //伤害
        public override void Damage()
        {
            Console.WriteLine("Causing precise damage!");
        }
}

(2)两个坐骑的具体实现例子

//(4.3)具体坐骑1:飞鹰
public class FlayEagle: Mount
{
    //物种
    public override void AnimalSpecies()
    {
        Console.WriteLine("I'm a one kinds of raptor!");
    }
    //运动方式
    public override void MotionType()
    {
        Console.WriteLine("I'm fly quickly!");
    }
}
//(4.4)具体坐骑2:角马
public class Gnu: Mount
{
    //物种
    public override void AnimalSpecies()
    {
        Console.WriteLine("I'm a one kinds of horse!");
    }
    //运动方式
    public override void MotionType()
    {
        Console.WriteLine("I'm run quickly!");
    }
}

3.3.3具体工厂的实现

(1)随意的创建了三个具体工厂,实现三个不同兵种的属性

//(5.1)具体角色工厂1--飞的精灵
public class FlyingElfFactory:CharacterFactory
{
    public override Weapon CreateWeapon() 
    { 
        return new HouyiBow();
    }
    public override Mount CreateMount()
    {
        return new FlayEagle();
    }
}
//(5.2)具体角色工厂2--骑刀兵
public class CavalryFactory : CharacterFactory
{
    public override Weapon CreateWeapon()
    {
        return new TangKnife();
    }
    public override Mount CreateMount()
    {
        return new Gnu();
    }
}
//(5.3)具体角色工厂3--弓骑兵
public class BowmanFactory : CharacterFactory
{
    public override Weapon CreateWeapon()
    {
        return new HouyiBow();
    }
    public override Mount CreateMount()
    {
        return new Gnu();
    }
}

3.3.4客户端的调用

(1)和工厂模式类似,使用多态很简单的实现了调用

//(1)通过抽象工厂模式创建对象1--飞天精灵
CharacterFactory characterFactory = new FlyingElfFactory();
Weapon weapon = characterFactory.CreateWeapon();
 weapon.ShowName();
weapon.Damage();
Mount mount = characterFactory.CreateMount();
mount.AnimalSpecies();
mount.MotionType();

3.4完整的代码实现

(1)工厂模式和客户端代码分成两个文件

(2)Factory.cs是工厂模式的代码,如下所示

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp6_abstractFactory
{
    //(1)抽象武器
    public abstract class Weapon
    {
        //名字
        public abstract void ShowName();
        //伤害
        public abstract void Damage();
    }
    //(2)抽象坐骑
    public abstract class Mount
    {
        //物种
        public abstract void AnimalSpecies();
        //运动方式
        public abstract void MotionType();
    }

    //(3)抽象角色工厂
    public abstract class CharacterFactory
    {
        public abstract Weapon CreateWeapon();
        public abstract Mount CreateMount();
    }

    //(4.1)具体武器1,刀
    public class TangKnife : Weapon
    {
        //名字
        public override void ShowName()
        {
            Console.WriteLine("I'm a Big Tang Knife!!");
        }
        //伤害
        public override void Damage()
        {
            Console.WriteLine("Causing Great damage!");
        }
    }
    //(4.2)具体武器2,弓
    public class HouyiBow : Weapon
    {
        //名字
        public override void ShowName()
        {
            Console.WriteLine("I'm a Bow used by Houyi!!");
        }
        //伤害
        public override void Damage()
        {
            Console.WriteLine("Causing precise damage!");
        }
    }

    //(4.3)具体坐骑1:飞鹰
    public class FlayEagle : Mount
    {
        //物种
        public override void AnimalSpecies()
        {
            Console.WriteLine("I'm a one kinds of raptor!");
        }
        //运动方式
        public override void MotionType()
        {
            Console.WriteLine("I'm fly quickly!");
        }
    }
    //(4.4)具体坐骑2:角马
    public class Gnu : Mount
    {
        //物种
        public override void AnimalSpecies()
        {
            Console.WriteLine("I'm a one kinds of horse!");
        }
        //运动方式
        public override void MotionType()
        {
            Console.WriteLine("I'm run quickly!");
        }
    }

    //(5.1)具体角色工厂1--飞的精灵
    public class FlyingElfFactory : CharacterFactory
    {
        public override Weapon CreateWeapon()
        {
            return new HouyiBow();
        }
        public override Mount CreateMount()
        {
            return new FlayEagle();
        }
    }

    //(5.2)具体角色工厂2--骑刀兵
    public class CavalryFactory : CharacterFactory
    {
        public override Weapon CreateWeapon()
        {
            return new TangKnife();
        }
        public override Mount CreateMount()
        {
            return new Gnu();
        }
    }

    //(5.3)具体角色工厂3--弓骑兵
    public class BowmanFactory : CharacterFactory
    {
        public override Weapon CreateWeapon()
        {
            return new HouyiBow();
        }
        public override Mount CreateMount()
        {
            return new Gnu();
        }
    }
}

(3)Program.cs的代码是客户端代码,如下所示


namespace ConsoleApp6_abstractFactory
{
    class Demo
    {
        static void CreateShowGame(CharacterFactory characterFactory)
        {
           // CharacterFactory characterFactory = new FlyingElfFactory();
            Weapon weapon = characterFactory.CreateWeapon();
            weapon.ShowName();
            weapon.Damage();
            Mount mount = characterFactory.CreateMount();
            mount.AnimalSpecies();
            mount.MotionType();
            Console.WriteLine("------------------");
        }
        static void Main()
        {
            //(1)通过抽象工厂模式创建对象1--飞天精灵
            CharacterFactory characterFactory = new FlyingElfFactory();
            Weapon weapon = characterFactory.CreateWeapon();
            weapon.ShowName();
            weapon.Damage();
            Mount mount = characterFactory.CreateMount();
            mount.AnimalSpecies();
            mount.MotionType();

            //第二种方使用
            Console.WriteLine("--------第二种方法使用----------");   
            CreateShowGame(new FlyingElfFactory());
            CreateShowGame(new CavalryFactory());
            CreateShowGame(new BowmanFactory());
        }
    }
}

(4)测试结果如下

(5)可以看出,客户端只有调用的时候,只要一个地方修改就行了

4三种工厂方式的比较

4.1简单工厂模式

4.2工厂方法模式

4.3抽象工厂模式

PS:抽象工厂可以一个工厂类对应多个对象(当然他们是逻辑上有关的)!

5、总结

5.1抽象工厂的特点

(1)抽象工厂模式中,客户client只和抽象工厂类、抽象工具累打交道,不和具体的实现打交道,详见本文第2幅图和最后一幅代码分析图。

(2)工厂模式属于设计模式中的创造型设计模式的一种。它的主要作用是协助我们创建对象,为创建对象提供最佳的方式。减少代码中的耦合程度,方便后期代码的维护。

(3)如果这一个类型新的对象要增加,只需要添加新的工具实现类和工厂实现类即可,客户看不到你添加的过程中干了什么,他对着新的工厂实现类已调用就好,其它都不用改

5.2代码怎么修改才好的反思

(1)原来的简单工厂,在添加新的对象的时候,除了添加新的工具类,还需要修改工厂的静态类,这就不合适了。为什么不合适呢?答:已编好的程序,这一段程序还和很多人都有关的,能不动就不动,否则危险!

(2)抽象工厂模式,在添加新的对象的时候,只需要添加新的工具实现类和工厂实现类,客户调用一下新的工厂实现类就好,没有动其他人的程序,OK!!!

展开阅读全文

页面更新:2024-02-12

标签:抽象   工厂   模式   坐骑   物种   对象   武器   代码   方式   产品

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top