首页 > 其他分享 >写给准备跳槽的小伙伴们的设计模式——工厂方法设计模式

写给准备跳槽的小伙伴们的设计模式——工厂方法设计模式

时间:2023-02-15 08:55:17浏览次数:54  
标签:return 跳槽 double ICalculator 小伙伴 设计模式 d2 public d1

概述

工厂方法模式(FactoryMethod),定义一个创建产品对象的工厂接口,让工厂子类决定实例化那一个产品类。我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,它不属于 23 种经典设计模式,它的缺点是增加新产品时会违背“开闭原则”(可以通过反射克服该缺点)。

工厂方法模式是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。


 

需求案例

我们先来看一看这样一个案例,小学生玩的四则运算,当客户输入两个数,然后输入一个操作符,获得结果!我们先用简单工厂写下逻辑代码,验证下简单工厂的缺点。

简单工厂代码

   /// <summary>
    ///  静态工作方法 实际上就是把创建对象的过程放到静态方法里面
    /// </summary>
    public class CalFactory
    {
        public static ICalculator GetCalculator(string oper)
        {
            ICalculator? calculator = null;
            switch (oper)
            {
                case "*":
                    calculator = new Mul();
                    break;
                case "+":
                    calculator = new Add();
                    break;
                case "-":
                    calculator = new Sub();
                    break;
                case "/":
                    calculator = new Div();
                    break;
            }
            return calculator;
        }
    }
   public interface  ICalculator
    {
        double GetResult(double d1,double d2);
    }

    public class Add : ICalculator
    {
        public double GetResult(double d1, double d2)
        {
           return d1+ d2;   
        }
    }
    public class Sub : ICalculator
    {
        public double GetResult(double d1, double d2)
        {
            return d1-d2;
        }
    }
    public class Mul : ICalculator
    {
        public double GetResult(double d1, double d2)
        {
            return d1* d2;
        }
    }
    public class Div : ICalculator
    {
        public double GetResult(double d1, double d2)
        {
            return d1 / d2;
        }
//C# 控制台调用
Console.WriteLine("简单工厂设计模式!");
Console.WriteLine("请输入操作数1");
var d1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("请输入操作数2");
var d2 = Convert.ToDouble(Console.ReadLine());
ICalculator calculator = null;
Console.WriteLine("请输入操作符");
string flag=Console.ReadLine();

calculator= CalFactory.GetCalculator(flag);   
double reslut= calculator.GetResult(d1,d2);
Console.WriteLine(reslut);

这个需求的代码逻辑很简单,一看基本就会,我们主要说下简单工厂模式的优缺点;

优点:

1、简单工厂设计模式解决了客户端直接依赖具体对象的问题,客户端消除了创建对象的责任,仅仅承担使用的责任。简单工厂模式实现了对责任的分割;
2、简单工厂起到了代码复用的作用;
缺点:
1、系统扩展困难,一旦加入新功能,就必须要修改工厂逻辑。破坏了开闭原则;
2、简单工厂集合了多有创建对象的逻辑,一旦不能正常工作,会导致整个系统出问题;

工厂方法代码

还是上面的需求,我们定义一个创建对象的接口,让子类决定实例化哪一个类。

    public interface ICalFactory
    {
        ICalculator GetCalculator();
    }
    public class MulFactory : ICalFactory
    {
        public ICalculator GetCalculator()
        {
            return new Mul();
        }
    }
  public class AddFactory : ICalFactory
    {
        public ICalculator GetCalculator()
        {
            return new Add();
        }
    }
  public class SubFactory : ICalFactory
    {
        public ICalculator GetCalculator()
        {
            return new Sub();
        }
    }
    public class DivFactory : ICalFactory
    {
        public ICalculator GetCalculator()
        {
            return new Div();
        }
    }
   public interface ICalculator
    {
        double GetResult(double d1, double d2);
    }

    public class Add : ICalculator
    {
        public double GetResult(double d1, double d2)
        {
            return d1 + d2;
        }
    }
    public class Sub : ICalculator
    {
        public double GetResult(double d1, double d2)
        {
            return d1 - d2;
        }
    }
    public class Mul : ICalculator
    {
        public double GetResult(double d1, double d2)
        {
            return d1 * d2;
        }
    }
    public class Div : ICalculator
    {
        public double GetResult(double d1, double d2)
        {
            return d1 / d2;
        }
    }
//C# 控制台调用
Console.WriteLine("请输入操作数1");
var d1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("请输入操作数2");
var d2 = Convert.ToDouble(Console.ReadLine());

Console.WriteLine("请输入操作符");
string flag = Console.ReadLine();

ICalFactory? calFactory = null;

switch (flag)
{
    case "*":
        calFactory = new MulFactory();
        break;
    case "+":
        calFactory = new AddFactory();
        break;
    case "-":
        calFactory = new SubFactory();
        break;
    case "/":
        calFactory = new DivFactory();
        break;
}

ICalculator calculator=calFactory?.GetCalculator();
var result= calculator.GetResult(d1, d2);
Console.WriteLine(result);

我们目前是使用了工厂方法设计模式来实现了需求,但能看到源码里面有一坨switch case,我们接下来通过反射处理switch case

没有switch case的工厂方法代码

 public class OperFactory:Attribute
    {
        public string  Oper { get;  }
        public OperFactory(string value)
        {
            Oper=value;
        }
    }
  public class ReflectionFactory
    {
        //根据用户输入的操作符 返回一个对象
        Dictionary<string, ICalFactory> dic=new Dictionary<string, ICalFactory>();
        public ReflectionFactory()
        {
            //拿到当前正在运行的程序集
            Assembly assembly= Assembly.GetExecutingAssembly();
            foreach (var item in assembly.GetTypes())
            {
                //IsAssignableFrom 表示item继承了ICalFactory或实现了ICalFactory
                if (typeof(ICalFactory).IsAssignableFrom(item)&&!item.IsInterface)
                {
                    OperFactory of= item.GetCustomAttribute<OperFactory>();
                    if (of != null)
                    {
                        //给键值对集合赋值
                        dic[of.Oper] = Activator.CreateInstance(item) as ICalFactory;
                    }
                }
            }
        }

        public ICalFactory GetFac(string s)
        {
            if (dic.ContainsKey(s))
            {
                return dic[s];
            }
            return null;
        }
    }
   public interface ICalFactory
    {
        ICalculator GetCalculator();
    }
    [OperFactory("*")]
    public class MulFactory : ICalFactory
    {
        public ICalculator GetCalculator()
        {
            return new Mul();
        }
    }
    [OperFactory("+")]
    public class AddFactory : ICalFactory
    {
        public ICalculator GetCalculator()
        {
            return new Add();
        }
    }
    [OperFactory("-")]
    public class SubFactory : ICalFactory
    {
        public ICalculator GetCalculator()
        {
            return new Sub();
        }
    }
    [OperFactory("/")]
    public class DivFactory : ICalFactory
    {
        public ICalculator GetCalculator()
        {
            return new Div();
        }
    }
//C# 控制台调用
ReflectionFactory reflectionFactory = new ReflectionFactory();
ICalFactory calFactory2=  reflectionFactory.GetFac(flag);
 var result2= calFactory2.GetCalculator().GetResult(d1, d2);
Console.WriteLine(result2);

总结

一个四则运算的需求,分别采用简单工厂和工厂方法实现,其实各有优缺点,使用哪种设计模式主要取决于自己的业务,有何疑问,欢迎交流。

标签:return,跳槽,double,ICalculator,小伙伴,设计模式,d2,public,d1
From: https://www.cnblogs.com/mhg215/p/17119131.html

相关文章

  • 设计模式之模版方法模式的钩子方法
     publicabstractclassSoyaMilk{//模版方法可以做成finaL,不让子类去覆盖finalvoidmake(){select();if(customerWantCondiments()){......
  • 代理设计模式
    代理设计模式​​1、代理设计模式​​​​1.1静态代理模式​​​​1.2动态代理模式​​1、代理设计模式  所谓代理,就是替别人完成一些事情。在Java开发中,我们也会遇到一......
  • 什么是设计模式?
    所谓设计模式,就是对经常出现的软件设计问题的成熟解决方案。很多人把设计模式想象成非常高深的概念,实际上设计模式仅仅是对特定问题的一种惯性思维。有些人喜欢抱着一本设......
  • 设计模式-简单工厂类
    简单工厂模式一个工厂类根据传入的参数,动态的决定去创建哪一个产品类。、前言介绍如果想要实现一个计算器功能,前台页面输入数字和运算符号,后台该如何去实现简单版本......
  • CSS架构之BEM设计模式
    为什么需要CSS架构?其实在日常开发CSS当中,会遇到许多的问题,使用设计模式能够很好的解决。例如在日常开发项目,需要组件化时,组件内部的class样式类管理就非常的杂乱。大部分......
  • python wxauto+OpenAI 搭了个微信小伙伴
    都知道ChatGPT火,没用过怎么知道他为什么火?于是好奇搞个玩玩。第一步:获取OPENAI_API_KEY首先你能要去官网注册账号后去创建一个keys具体略这一步比较关键,仁者见仁智者......
  • 前端设计模式:观察者与发布订阅模式
    观察者模式描述:观察者模式(ObserverPattern)由被观察者和观察者组成,观察者可以是多个,被观察者维护着多个观察者,如添加或删除观察者;当被观察着数据变化时,会通过广播的方式......
  • 设计模式(七)----创建型模式之建造者模式
    1、概述将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。分离了部件的构造(由Builder来负责)和装配(由Director负责)。从而可以构造出复杂的......
  • 6 mvvm设计模式
    Vue的createApp和mount方法讲解​​简介​​​​最常见的Vue初级代码​​​​createApp()和mount()方法讲解​​​​createApp()方法的基本参数讲解​​​​如何获......
  • 求职、跳槽中英文简历模板下载集合
    求职、跳槽简历模板下载放送?​​英文简历(客户服务代表)​​?​​CUSTOMERSERVICEREPRESENTATIVE(Sales)​​?​​英文简历(酒店文职人员)​​?​​HOTELCLERK​​?​......