设计模式(0)简单工厂模式

设计模式(1)单例模式(Singleton)

源码地址

0 工厂方法模式简介

0.0 工厂方法模式定义

工厂方法模式是在简单工厂模式基础上,为解决更复杂的对象创建问题而衍生进化出来的一种创建型模式。

工厂方法模式的核心思想是定义一个用于创建对象的接口,让其子类去决定去实例化哪个具体类的对象,工厂方法模式可以使一个类的实例化动作延迟到其子类。

工厂方法模式结构图如下

0.1 工厂方法模式应用场景

还接着祭坛生产英雄的示例,我们已经在简单工厂模式一文中通过创建简单工厂方法类,来实现暗夜精灵种族4个英雄的创建

/// <summary>/// 创建英雄的静态方法/// </summary>/// <param name="heroName">英雄名称</param>/// <returns></returns>public static IHero CreateHero(string heroName){switch (heroName){case "DH":return new DH();case "WD":return new WD();case "KOG":return new KOG();case "POM":return new POM();default:return null;}}

假设现在我们要创建不死族的英雄怎么办呢,如果依然使用简单工厂方法类,则首先需要实现不死族四个英雄类。

/// <summary>
/// 死亡骑士
/// </summary>
public class DK : IHero
{/// <summary>/// 秀出自己的技能/// </summary>public void ShowSkills(){Console.WriteLine("我是死亡骑士,我会死亡缠绕、死亡契约、邪恶光环和操纵死尸。");}
}

/// <summary>
/// 巫妖
/// </summary>
public class Lich : IHero
{/// <summary>/// 秀出自己的技能/// </summary>public void ShowSkills(){Console.WriteLine("我是巫妖,我会霜冻新星、寒冰甲、黑暗仪式和死亡凋零。");}
}

/// <summary>
/// 地穴领主
/// </summary>
public class DL : IHero
{/// <summary>/// 秀出自己的技能/// </summary>public void ShowSkills(){Console.WriteLine("我是地穴领主,我会穿刺、刺盾、腐蚀甲虫和蝗群。");}
}

/// <summary>
/// 恐惧魔王
/// </summary>
public class CL : IHero
{/// <summary>/// 秀出自己的技能/// </summary>public void ShowSkills(){Console.WriteLine("我是恐惧魔王,我会腐臭群蜂、睡眠、吸血光环、地狱火。");}
}

然后需要修改工厂方法,增加switch语句中的类型,将不死族四个英雄创建逻辑添加进去。

/// <summary>
/// 创建英雄的静态方法
/// </summary>
/// <param name="heroName">英雄名称</param>
/// <returns></returns>
public static IHero CreateHero(string hero
{switch (heroName){//暗夜精灵case "DH":return new DH();case "WD":return new WD();case "KOG":return new KOG();case "POM":return new POM();// 不死族case "DK":return new DK();case "Lich":return new Lich();case "CL":return new CL();case "DL":return new DL();default:return null;}
}

还有兽族及人族,也需要如此修改。到此我们会感觉存在有以下问题

1、随着英雄的增多,简单工厂类需要反复修改。

2、简单工厂类过于庞大,职责混乱,负责了四个种族所有英雄的创建,而实际上,玩家在进入游戏时已经选好了自己的种族,只有可能创建所选种族的英雄。

我们到了这里,首先要想到的是,既然四个种族,分别有自己的祭坛,产生改种族的英雄,我们应该将简单工厂类按照种族进行职责拆分,此时参考上面提到的工厂方法模式定义以及结构图,我们会发现,现在是到了工厂方法模式出场的时候了。

1 工厂方法模式详解

1、提炼工厂方法接口

将原来的简单工厂类,进一步提炼为一个工厂方法接口,其包含一个名为CreateHero的接口。

/// <summary>
/// 工厂方法接口
/// </summary>
public interface IFactory
{/// <summary>/// 创建英雄的方法/// </summary>/// <param name="heroName">英雄名称</param>/// <returns></returns>IHero CreateHero(string heroName);
}

2、实现四个种族的工厂方法

四个种族创建英雄的工厂方法继承自工厂方法接口,实现CreateHero。

/// <summary>
/// 暗夜精灵种族英雄工厂类
/// </summary>
public class NEFactory : IFactory
{/// <summary>/// 创建英雄的静态方法/// </summary>/// <param name="heroName">英雄名称</param>/// <returns></returns>public IHero CreateHero(string heroName){switch (heroName){//暗夜精灵case "DH":return new DH();case "WD":return new WD();case "KOG":return new KOG();case "POM":return new POM();default:return null;}}
}

/// <summary>
/// 不死族英雄工厂类
/// </summary>
public class UDFactory : IFactory
{/// <summary>/// 创建英雄的静态方法/// </summary>/// <param name="heroName">英雄名称</param>/// <returns></returns>public IHero CreateHero(string heroName){switch (heroName){// 不死族case "DK":return new DK();case "Lich":return new Lich();case "CL":return new CL();case "DL":return new DL();default:return null;}}
}

3、客户端调用

static void Main(string[] args)
{IFactory factory = new NEFactory();  // 初始化一个暗夜精灵族的英雄工厂Console.WriteLine("我在开局时选择了暗夜精灵族,我的首发英雄是DH。");IHero dh = factory.CreateHero("DH");dh.ShowSkills();factory = new UDFactory();  // 初始化一个不死族的英雄工厂Console.WriteLine("我在开局时选择了不死族,我的首发英雄是DK。");IHero dk = factory.CreateHero("DK");dk.ShowSkills();Console.ReadLine();
}

4、通过反射实例化具体的工厂方法类

在实际应用中跟上面不同种族创建英雄的例子类似,一般在系统启动时就已经确定要使用哪种方法实例化工厂方法类,通常我们可以将工厂类的实例化通过配置文件的方式确定,从而避免源码的修改。

string factoryName = ConfigurationManager.AppSettings["FactoryName"]; // 读取配置文件
IFactory factory = (IFactory)Assembly.Load("FactoryMethodPattern").CreateInstance("FactoryMethodPattern." + factoryName); // 实例化配置的工厂方法类

2 总结

工厂方法模式具有以下优点

1、更容易对现有功能进行扩展,如果有新的需求,只需要实现一个相应的工厂方法实现类即可,无需修改现有代码。

2、不同工厂方法类,实现了单一职责的设计原则。

工厂方法模式的缺点

由于具体的对象由具体指定的工厂方法类创建,导致具体产品和工厂方法类之间具有较强的耦合性

转载于:https://www.cnblogs.com/fonour/p/7055737.html

设计模式(2)工厂方法模式(Factory Method)相关推荐

  1. 【设计模式】工厂方法模式 Factory Method Pattern

    在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...

  2. 设计模式之工厂方法模式(Factory Method)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式包括:1.FactoryMethod(工厂方法模式):2.Abstract Factory(抽象工厂模式):3.Sin ...

  3. 设计模式之工厂方法模式---factory method

    模式的介绍 模式的定义 Define an interface for creating an object,but let subclassed decide which class to inst ...

  4. 设计模式之工厂方法模式(Factory Method Pattern)

    一.工厂方法模式的诞生 在读这篇文章之前,我先推荐大家读<设计模式之简单工厂模式(Simple Factory Pattern)>这篇文档.工厂方法模式是针对简单工厂模式中违反开闭原则的不 ...

  5. 设计模式题目-工厂方法模式(Factory Method)

    设计一个程序来读取多种不同存储格式的图片,针对每一种图片格式都设计一个图片读取器(ImageReader),如GIF格式图片读取器(GifReader)用于读取GIF格式的图片,JPEG格式图片读取器 ...

  6. 工厂方法模式(Factory Method)简介

    工厂方法模式 名字 跟已经介绍的 简单工厂模式很类似. 实际上它们的模型也是十分相似的. 我们先看看工厂模式的定义. 一. 工厂方法(Factory Method)模式定义 教材上是这样写的: 工厂方 ...

  7. 设计模式之六:工厂方法模式(Factory method Pattern)

    工厂方法(Factory Method)模式就是定义一个创建对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责具体产品的创建,仅提供了具体工厂子类必须实现的接口,这样核心类成为一个抽象 ...

  8. 浅谈C++设计模式之工厂方法(Factory Method)

    为什么要用设计模式?根本原因是为了代码复用,增加可维护性. 面向对象设计坚持的原则:开闭原则(Open Closed Principle,OCP).里氏代换原则(Liskov Substitution ...

  9. 软件工程 - 设计模式学习之工厂方法模式Factory Method

    在现实生活中我们可以看见,乐事在卖薯片,可比克也在卖. 我敢肯定的说它们各自都有自己的工厂来生产薯片,而且生产出来的薯片味道还是不一样的. 这就是我们这里所谓的工厂方法模式. 我们来看看这个模式的UM ...

  10. C++实现工厂方法模式Factory Method Pattern

    设计原则6:要依赖抽象,不要依赖具体类.(又称依赖倒置原则Dependency Inversion Principle) 不能让高层组件依赖低层组件,而且,不管高层组件或低层组件,两者都应该依赖于抽象 ...

最新文章

  1. Shiro结合Redis解决集群中session同步问题
  2. pip安装库包以及.whl库包、.tar.gz库包具体方式
  3. Android学习笔记:Activity-ListView
  4. 转python version 2.7 required,which was not found in the registry
  5. SAP Cloud Application Programming 里的@(path) 注解
  6. 苏宁智慧家庭助跑智慧零售
  7. 【C++】反向迭代器(rbegin,rend)(转载)
  8. 网络安全系统性学习路线「全文字详细介绍」
  9. TFS2010升级至TFS2013完全指南(更换服务器)
  10. java启动报错Port already in use: 1099
  11. 万能python,画个滑稽来玩玩
  12. safari浏览器找不到服务器
  13. SaaS企业级免费市场似乎即将过去
  14. 解析社交电商运营模式玩法的秘密?
  15. 【计算机网络】湖科大微课堂笔记 p7-10 计算机网络体系结构:常见的计算机网络体系结构、必要性、分层思想、专业术语
  16. AirSim学习和踩坑记录(不定时更新)
  17. pdf格式如何压缩大小?压缩pdf大小的方法?
  18. RN measure获取元素坐标失效问题 (仅安卓端)
  19. 计算机应用基础 双语 答案,计算机应用基础(双语)课件PPTChax
  20. OPPO入股少儿编程教育平台编程猫 官网域名为纯字母域名codemao.cn

热门文章

  1. MTD NANDFLASH驱动相关知识介绍
  2. 一些与算法有关的网站
  3. 一个用泛型隐式传递权限关键字的方法
  4. 获取执行SQL语句的返回结果
  5. 全球15个顶级技术类博客
  6. 基础数据结构【二】————动态数组,单向链表及链表的反转
  7. Linux查看本机端口
  8. C#下用P2P技术实现点对点聊天
  9. Visual C# .NET 2003 语言的改变
  10. 结合ashx来在DataGrid中显示从数据库中读出的图片