(1)https://www.jianshu.com/p/6060e0632071
(2)https://www.bilibili.com/video/BV1Jz4y1d7TX/?p=3
(1)在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
(2)如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?
(3)提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。(《设计模式》GoF)
(1)注意,下图中具体的产品A1和B1相互依赖(是一伙的,搭配的),A2和B2相互依赖(是一伙的,搭配的)
(2)客户程序只依赖于AbstractFactory、AbstractProductA和AbstractProductB三个抽象类。
(3)如果这个时候有新的类型的对象要添加,比如说要创建未来风格的A3和B3,这个时候只要添加新的工厂类就可以。(客户的依赖还是那3项,没有任何改变)
(1)abstract和interface的区别详见我的教程https://www.toutiao.com/article/7288888037336220223/
(2)接口相对来说更底层更抽象,abstract可以带更多自身具体的实现,根据需要看看要不要进一步抽象为interface。
(3)不管用abstract还是interface实现抽象工厂,思想是一样的。
(1)想了半天,想了个无聊的游戏例子,需要创建一个游戏对象,属性包括:武器,坐骑....它们会有很多组合,以后还可能添加很多其它的属性。
(2)这个例子的图我简单画了一下,如下所示
(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();
}
(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!");
}
}
(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();
}
}
(1)和工厂模式类似,使用多态很简单的实现了调用
//(1)通过抽象工厂模式创建对象1--飞天精灵
CharacterFactory characterFactory = new FlyingElfFactory();
Weapon weapon = characterFactory.CreateWeapon();
weapon.ShowName();
weapon.Damage();
Mount mount = characterFactory.CreateMount();
mount.AnimalSpecies();
mount.MotionType();
(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)可以看出,客户端只有调用的时候,只要一个地方修改就行了
PS:抽象工厂可以一个工厂类对应多个对象(当然他们是逻辑上有关的)!
5、总结
(1)抽象工厂模式中,客户client只和抽象工厂类、抽象工具累打交道,不和具体的实现打交道,详见本文第2幅图和最后一幅代码分析图。
(2)工厂模式属于设计模式中的创造型设计模式的一种。它的主要作用是协助我们创建对象,为创建对象提供最佳的方式。减少代码中的耦合程度,方便后期代码的维护。
(3)如果这一个类型新的对象要增加,只需要添加新的工具实现类和工厂实现类即可,客户看不到你添加的过程中干了什么,他对着新的工厂实现类已调用就好,其它都不用改。
(1)原来的简单工厂,在添加新的对象的时候,除了添加新的工具类,还需要修改工厂的静态类,这就不合适了。为什么不合适呢?答:已编好的程序,这一段程序还和很多人都有关的,能不动就不动,否则危险!
(2)抽象工厂模式,在添加新的对象的时候,只需要添加新的工具实现类和工厂实现类,客户调用一下新的工厂实现类就好,没有动其他人的程序,OK!!!
页面更新:2024-02-12
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号