网站首页 > 教程分享 正文
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简单工厂模式
- 该模式不属于GoF列出的23种模式之一,但它确是学习其他几个工厂模式的基础,也是最容易的。
- 它实现了创建对象和使用对象分离的原则,由工厂类来负责对象的创建。比如,一个形状Shape抽象类,它是其他具体形状类的父类。
- 该模式存在缺陷:当有新的产品(如具体形状Heart)需要添加时,不得不修改工厂类的源代码,这违背了设计模式的开闭原则(有关开闭原则请自行了解:()。
4.2工厂方法模式
- 这是解决简单工厂模式缺陷的升级模式。
- 当类的数量庞大时,可以给每一个类构建对应的工厂类,调用者不必考虑类的创建而只用来配置和使用类的对象。
- 工厂方法模式在具体的工厂类中也可以提供多种方法来初始化创建类的实例,调用者只需传入需要的参数即可。每个具体的工厂类对应具体的产品类,都实现了一个抽象工厂接口和抽象产品接口,因此此模式也称多态工厂模式。
- 缺点:当类过多时势必引起类文件的臃肿,增加了代码的开销。所以,抽象工厂模式随之出现了。
4.3抽象工厂模式
- 可以创建一系列相关联的产品,而不是对每一个产品都对应一个工厂类。
- 它与工厂方法模式的区别在于:工厂方法对每一个产品都提供一个工厂类,而抽象工厂模式统一为相关联的产品(一个产品家族,如某品牌制作的电视、电脑等;某样式库下的按钮、文本框等)提供一个具体工厂类,在此类中定义用来创建各个具体产品的各个方法,这样一个工厂类可以创建一个产品族(包含多个相关联产品)的对象,极大减少了类的数量。
PS:抽象工厂可以一个工厂类对应多个对象(当然他们是逻辑上有关的)!
5、总结
5.1抽象工厂的特点
(1)抽象工厂模式中,客户client只和抽象工厂类、抽象工具累打交道,不和具体的实现打交道,详见本文第2幅图和最后一幅代码分析图。
(2)工厂模式属于设计模式中的创造型设计模式的一种。它的主要作用是协助我们创建对象,为创建对象提供最佳的方式。减少代码中的耦合程度,方便后期代码的维护。
(3)如果这一个类型新的对象要增加,只需要添加新的工具实现类和工厂实现类即可,客户看不到你添加的过程中干了什么,他对着新的工厂实现类已调用就好,其它都不用改。
5.2代码怎么修改才好的反思
(1)原来的简单工厂,在添加新的对象的时候,除了添加新的工具类,还需要修改工厂的静态类,这就不合适了。为什么不合适呢?答:已编好的程序,这一段程序还和很多人都有关的,能不动就不动,否则危险!
(2)抽象工厂模式,在添加新的对象的时候,只需要添加新的工具实现类和工厂实现类,客户调用一下新的工厂实现类就好,没有动其他人的程序,OK!!!
猜你喜欢
- 2024-10-18 设计模式之 抽象工厂(抽象工厂模式的简单应用)
- 2024-10-18 Aha!设计模式(3)-抽象工厂(2)(抽象工厂模式结构图)
- 2024-10-18 Java经典设计模式-抽象工厂模式(抽象工厂模式在spring的应用)
- 2024-10-18 Java高级编程细节——工厂模式之抽象工厂
- 2024-10-18 java与设计模式-简单工厂-工厂方法-抽象工厂
- 2024-10-18 简单工厂,工厂方法,抽象工厂(简单工厂,工厂方法,抽象工厂区别)
- 2024-10-18 Aha!设计模式(1)-抽象工厂(1)(抽象工厂实例)
- 2024-10-18 抽象工厂模式(Abstract Factory)(抽象工厂模式的意图是)
- 2024-10-18 设计模式记录-抽象工厂模式(抽象工厂模式与工厂方法模式)
- 2024-10-18 你还在new对象吗?用个“抽象工厂模式”生产对象它不香吗
你 发表评论:
欢迎- 最近发表
-
- 有了这份900多页的Android面试指南,你离大厂Offer还远吗?
- K2 Blackpearl 流程平台总体功能介绍:常规流程功能
- 零基础安卓开发起步(一)(安卓开发入门视频)
- 教程:让你的安卓像Windows一样实现程序窗口化运行
- Android事件总线还能怎么玩?(事件总线有什么好处)
- Android 面试被问“谈谈架构”,到底要怎样回答才好?
- Android开发工具Parcel和Serialize
- Android 中Notification的运用(notification widget安卓)
- Android退出所有Activity最优雅的方式
- MT管理器-简单实战-去除启动页(mt管理器怎么去除软件弹窗)
- 标签列表
-
- css导航条 (66)
- sqlinsert (63)
- js提交表单 (60)
- param (62)
- parentelement (65)
- jquery分享 (62)
- check约束 (64)
- curl_init (68)
- sql if语句 (69)
- import (66)
- chmod文件夹 (71)
- clearinterval (71)
- pythonrange (62)
- 数组长度 (61)
- javafx (59)
- 全局消息钩子 (64)
- sort排序 (62)
- jdbc (69)
- php网页源码 (59)
- assert h (69)
- httpclientjar (60)
- postgresql conf (59)
- winform开发 (59)
- mysql数字类型 (71)
- drawimage (61)
本文暂时没有评论,来添加一个吧(●'◡'●)