zoukankan      html  css  js  c++  java
  • 设计模式整理之简单工厂

    具体实现代码:

    using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Text;
     using System.Threading.Tasks;
    
    namespace 设计模式实例
    {
         class Program
         {
             /// <summary>
             /// 考虑一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮
             /// (如圆形按钮、矩形按钮、菱形按钮等), 这些按钮都源自同一个基类,
             /// 不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈现不同的外观,
             /// 如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,
             /// 只需要知道表示该按钮类的一个参数,并提供一个调用方便的方法,
             /// 把该参数传入方法即可返回一个相应的按钮对象,此时,就可以使用简单工厂模式。
             /// 
             /// </summary>
             /// <param name="args"></param>
             static void Main(string[] args)
             {
                 Operation oper;
                 Console.Write("请输入第一个数: ");
                 string strNum1 = Console.ReadLine();
                 Console.Write("请输入操作符(+ - * /): ");
                 string strOperate = Console.ReadLine();
                 oper = OperationFactory.CreateOperate(strOperate);
                 Console.Write("请输入第二个数: ");
                 string strNum2 = Console.ReadLine();
                 oper.Num1 = Convert.ToDouble(strNum1);
                 oper.Num2 = Convert.ToDouble(strNum2);
                 string Result = "";
                 Result = Convert.ToString(oper.GetResult());
                 Console.WriteLine("结果是:" + Result);
                 Console.ReadKey(true);
             }
         }
         /// <summary>
         /// 就此问题个人理解:
         /// 1、实现方法:子类继承并重写父类方法,父类只接受处理的事务,而不是自己执行,而是交给
         ///             子类对象去实现,各个对象具有父类共同属性,而执行不同操作
         /// 2、具体实现:
         /// 工厂:工厂角色负责实现创建所有实例的内部逻辑
         /// 抽象产品角色:抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口
         /// 具体产品角色:具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例
         /// </summary>
         /*
          * 说通俗点有点像面向对象编程中的多态性,一个基类,有多个派生类,
          * 在另外的调用程序中,根据参数来决定返回这个基类的哪个具体的派生类,
          * 返回值为基类类型,因为基类的引用可以指向派生类对象,
          * 而且这些所有的派生类都包含有基类的函数,也就是说派生类中有相同的函数
          * 但是函数的实现可能不同。
          */
    
        public class OperationFactory
         {
             public static Operation CreateOperate(string operate)
             {
                 Operation oper = null;
                 switch (operate)
                 {
                     case "+":
                         oper = new OperationAdd();
                         break;
                     case "-":
                         oper = new OperationSub();
                         break;
                     case "*":
                         oper = new OperationMul();
                         break;
                     case "/":
                         oper = new OperationDiv();
                         break;
                 }
                 return oper;
             }
         }
    
        public class OperationDiv : Operation
         {
             public override double GetResult()
             {
                 try
                 {
                     double result = 0;
                     //            if (Num2 == 0)
                     //                throw new Exception("除数不为0");
                     result = Num1 / Num2;
                     return result;
                 }
                 catch (Exception e)
                 {
                     Console.WriteLine(e);
                     throw;
                 }
             }
         }
    
        public class OperationMul : Operation
         {
             public override double GetResult()
             {
                 double result = 0;
                 result = Num2 * Num1;
                 return result;
             }
         }
    
        public class OperationSub : Operation
         {
             public override double GetResult()
             {
                 double result = 0;
                 result = Num1 – Num2;
                 return result;
             }
         }
    
        public class OperationAdd : Operation
         {
             public override double GetResult()
             {
                 double result = 0;
                 result = Num2 + Num1;
                 return result;
             }
         }
    
        public class Operation
         {
             public double Num1 { get; set; }
             public double Num2 { get; set; }
             public virtual double GetResult()
             {
                 double result = 0;
                 return result;
             }
         }
     }

    模式分析
    •将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
    •在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,在实际开发中,还可以在调用时将所传入的参数保存在XML等格式的配置文件中,修改参数时无须修改任何源代码。
    •简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
    •简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。


    简单工厂模式的优点
    •工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
    •客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
    •通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

    简单工厂模式的缺点
    •由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
    •使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
    •系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
    •简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

    适用环境

    在以下情况下可以使用简单工厂模式:
    •工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
    •客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。





    以上收藏自https://design-patterns.readthedocs.io/zh_CN/latest/index.html,有问题,不吝赐教!

  • 相关阅读:
    SQL常用优化手法
    winform 文件上传
    在主线程中开启同步任务,为什么会阻塞线程
    KVC与KVO
    android shape的使用
    如何导入开源工程
    图片资源的设定
    如何进行程序的反编译和防止反编译
    log的管理
    通过反射机制拿到被隐藏的类(获取应用程序的缓存大小)
  • 原文地址:https://www.cnblogs.com/fenqinearl/p/10704710.html
Copyright © 2011-2022 走看看