设计模式之-工厂模式

简介: 前言 回顾上篇的设计模式之-简单工厂模式 我们可以从中发现一些问题。 先看看以计算器为例的简单工厂的结构图如下: 那此时我们换成工厂模式呢?我们先看看工厂的结构图: 承接上篇计算器为例,我们需要新建一个工厂接口 /// /// 构建一个工厂接口 /// ...

前言

回顾上篇的设计模式之-简单工厂模式 我们可以从中发现一些问题。

先看看以计算器为例的简单工厂的结构图如下:

那此时我们换成工厂模式呢?我们先看看工厂的结构图:

承接上篇计算器为例,我们需要新建一个工厂接口

 /// <summary>
    /// 构建一个工厂接口
    /// </summary>
    interface IFactory
    {
        Operaion CreateOperation();
    }

然后呢,为加减乘法各建一个具体的工厂实现接口

 //然后加减乘法各建一个具体的工厂实现接口
    class AddFactory : IFactory
    {
        public Operaion CreateOperation()
        {
            return new OpertionAdd();
        }
    }
    class SubFactory : IFactory
    {
        public Operaion CreateOperation()
        {
            return new OperationSub();
        }
    }
    class MulFactory : IFactory
    {
        public Operaion CreateOperation()
        {
            return new OperationMul();
        }
    }
    class DivFactory : IFactory
    {
        public Operaion CreateOperation()
        {
            return new OperationDiv();
        }
    }

客户端调用

 static void Main(string[] args)
        {
            try
            {
                Console.Write("请输入数字A:");
                string strNumberA = Console.ReadLine();
                Console.Write("请选择运算符号(+、-、*、/):");
                string strOperate = Console.ReadLine();
                Console.Write("请输入数字B:");
                string strNumberB = Console.ReadLine();
                //调用工厂进行计算
                IFactory operFactory = new AddFactory();
                Operaion oper = operFactory.CreateOperation();
                oper.NumberA =double.Parse(strNumberA);
                oper.NumberB =double.Parse(strNumberB);
                //返回计算结果
                var  strResult = oper.GetResult();
                Console.WriteLine("结果是:" + strResult);
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine("您的输入有错:" + ex.Message);
            }
        }

Why?为什么要这么写呢?上一篇的简单工厂已经很容易就实现了这个效果,为什么还要新加这个工厂来“复杂”化这个问题呢?

其实不然,简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了具体产品的依赖。

就像计算器,客户端不用管该用哪个类的实例,只需要把"+"给工厂,工厂自动就给出了相应的实例,客户端只要去做运算就可以了。但问题也在这里,如果要加一个‘求M数的N次方’功能,我们是一定要给运算工厂类的方法里加‘Case’分支条件的,既是修改了原有的类。这样就违背了我们开放-封闭原则。于是工厂方法就来了

这样的话,我们要增加‘求M数的N次方’的功能时,就不需要更改原有的工厂类了,只需要增加此功能的运算类和相应的工厂类就可以了。这就完全符合开放-封闭原则。

巩固

 以大学生学习‘雷锋’好人好事为例。首先是雷锋类:拥有扫地、洗衣、买米等方法

 //雷锋类
    class LeiFeng
    {
        public void Sweep()
        {
            Console.WriteLine("扫地");
        }
        public void Wash()
        {
            Console.WriteLine("洗衣");
        }
        public void BuyRice()
        {
            Console.WriteLine("买米");
        }
    }

然后‘学雷锋大学生’类继承‘雷锋’类

/// <summary>
    /// 学雷锋的大学生,继承‘雷锋’
    /// </summary>
    class Undergraduate : LeiFeng
    { }

然后客户端实现

                LeiFeng xueleifeng = new Undergraduate();
                xueleifeng.BuyRice();
                xueleifeng.Sweep();
                xueleifeng.Wash();

有一个问题,如果有三个人去学‘雷锋做好事,该怎么写呢?’

难道是写成?

      LeiFeng xueleifeng = new Undergraduate();
                xueleifeng.BuyRice();
                LeiFeng xueleifeng2 = new Undergraduate();
                xueleifeng.Sweep();
                LeiFeng xueleifeng3 = new Undergraduate();
                xueleifeng.Wash();

此时,就非常不合适了,老人不需要知道是谁来做好事,他只需要知道学雷锋的人来帮忙就可以ile,这样写我们需要更改多个实例化的地方。我们应该增加‘社区志愿者’类

 /// <summary>
    /// 社区志愿者
    /// </summary>
    class Volunteer : LeiFeng
    { }

再写简单工厂类

/// <summary>
    /// 简单雷锋工厂
    /// </summary>
    class SimpleFactory
    {
        public static LeiFeng CreateLeiFeng(string type)
        {
            LeiFeng result = null;
            switch (type)
            { 
                case "学雷锋的大学生":
                    result = new Undergraduate();
                    break;
                case "社区志愿者":
                    result=new Volunteer();
                    break;
            }
            return  result;
        }
    }

客户端的代码,如果要换,就只需要换‘学雷锋的大学生为‘社区志愿者’’

                //简单工厂模式
                LeiFeng studentA = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
                studentA.BuyRice();
                LeiFeng studentB = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
                studentA.Sweep();
                LeiFeng studentC = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
                studentA.Wash();

好,此时我们就发现,在任何实例化的时候写出这个工厂的代码,这里有重复,就出现了坏的味道,此时,我们再用工厂模式写一遍。

/// <summary>
    /// 雷锋工厂
    /// </summary>
    interface IFactory
    {
        LeiFeng CreateLeiFeng();
    }
    /// <summary>
    /// 学雷锋的大学生工厂
    /// </summary>
    class UndergraduateFacotry : IFactory
    {
        public LeiFeng CreateLeiFeng()
        {
            return new Undergraduate();
        }
    }
    /// <summary>
    /// 社区志愿者工厂
    /// </summary>
    class VolunteerFactory : IFactory
    {
        public LeiFeng CreateLeiFeng()
        {
            return new Volunteer();
        }
    }

客户端调用的时候只需要如下就可以了

         //工厂方法模式
                IFactory factory = new UndergraduateFacotry();//要换成‘社区志愿者’,修改这里即可
                LeiFeng student = factory.CreateLeiFeng();
                student.BuyRice();
                student.Sweep();
                student.Wash();

小结

工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。

但以上并不是最佳做法,利用‘反射’可以解决避免分支判断的问题。

未完待更新。。。。

  • 感谢你的阅读。如果你觉得这篇文章对你有帮助或者有启发,就请推荐一下吧~你的精神支持是博主强大的写作动力。欢迎转载!
  • 博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高(其实是个菜B),不足和错误之处在所难免,希望大家能够批评指出。
  • 欢迎加入.NET 从入门到精通技术讨论群→523490820 期待你的加入
  • 不舍得打乱,就永远学不会复原。被人嘲笑的梦想,才更有实现的价值。
  • 我的博客:http://www.cnblogs.com/zhangxiaoyong/
目录
相关文章
|
1月前
|
设计模式 Java 关系型数据库
设计模式——工厂模式
工厂模式介绍、静态简单工厂模式、工厂方法模式、抽象工厂模式、JDK 源码分析
设计模式——工厂模式
|
4月前
|
设计模式 数据格式 XML
设计模式-工厂模式-1-1
【6月更文挑战第10天】本文介绍了工厂模式的两种主要类型:简单工厂和工厂方法。简单工厂模式通过工厂类动态创建对象,例如根据配置文件后缀选择不同解析器。为提高可读性和复用性,可将创建逻辑封装到独立类中。当需添加新解析器时,可能涉及对工厂类的修改,但这在偶尔调整时可接受。工厂方法模式则通过多态消除if分支,增加扩展性,更符合开闭原则。当需要新增解析器时,只需创建实现特定接口的新工厂类。
30 2
设计模式-工厂模式-1-1
|
5月前
|
设计模式 消息中间件 Java
设计模式之工厂模式(C++)
设计模式之工厂模式(C++)
78 0
|
5月前
|
设计模式 前端开发 API
【设计模式】之工厂模式
工厂模式是一种常用的创建对象的设计模式,它通过封装对象的创建逻辑,提供统一的接口,实现了代码的解耦和可扩展性。在实际开发中,可以根据具体需求选择是否使用工厂模式来创建对象。工厂模式可以应用于任何需要创建对象的场景。通过使用工厂模式,我们可以提高代码的可维护性、可扩展性和可测试性,使得代码更加灵活和易于理解。
73 0
|
11月前
|
设计模式 Java C#
设计模式之工厂模式(2)
接着,我们定义一个抽象工厂类AbstractFactory,它有两个抽象方法createShape和createColor,分别返回一个Shape对象和一个Color对象: java
48 0
|
设计模式
设计模式之工厂模式
设计模式之工厂模式
62 0
|
设计模式
【设计模式】工厂模式
【设计模式】工厂模式
|
设计模式 消息中间件 Java
一起来学设计模式之工厂模式
前言 目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~ 本节给大家讲一下设计模式中的工厂模式~ 本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~ 工厂模式 工厂模式是一种常用的设计模式,它提供了一种创建对象的方式,该方式隐藏了对象创建的细节并提供了一个通用的接口,从而使得代码更加灵活和可扩展。在工厂模式中,我们将对象的创建过程封装到一个工厂类中,通过工厂类来创建具体的对象,这样客户端就不需要关心对象的创建过程,只需要调用工厂类提供的接口来获取所需的对象即可。
|
设计模式 Java 测试技术
浅谈设计模式 - 工厂模式(六)
在第一篇里面已经介绍过简单工厂了,但是工厂模式里面不仅仅是简单工厂,还存在工厂方法和抽象工厂,并且从严格意义来讲简单工厂不能算是一种设计模式,本次的文章针对工厂的进化来展开讲一讲工厂模式的三种常见形式:简单工厂、工厂方法、抽象工厂。
68 0
|
设计模式 Java uml
《设计模式》工厂模式
《设计模式》工厂模式
《设计模式》工厂模式