首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C#设计模式——(创建型-工厂方法设计模式)

C#设计模式——(创建型-工厂方法设计模式)

原创
作者头像
用户10053120
修改2022-10-08 15:33:02
修改2022-10-08 15:33:02
3210
举报
文章被收录于专栏:C# 设计原则C# 设计原则

一、工厂方法设计模式定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化,推迟到子类。

  • 抽象工厂角色ICalFactory

工厂方法模式的核心,是具体的工厂角色必须实现的接口或者必须继承的抽象类;

  • 具体工厂角色 AddFactory SubFactory

包含和具体业务逻辑有关的代码,由应用程序调用以创建对应的具体产品对象;

  • 抽象产品角色 ICalculator

是具体产品继承的父类或者接口

  • 具体产品角色类 Add Sub Mul Div

具体工厂角色创建的对象,就是该类的实例

二、工厂方法设计模式代码

代码语言:javascript
复制
public interface ICalculator   
{
    public 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;
    }
}
代码语言:javascript
复制
/******************************************
public class CalFactory
{
   public static ICalculator GetCalculator()
   {
   //现在是抽象依赖细节,应该是细节依赖抽象
   }
}
*******************************************/
//把创建对象这件事封装成抽象
public interface ICalFactory
{
   ICalculator GetCalculator();
}
public class AddFactory:ICalFactory//细节依赖抽象
{
   public ICalculator GetCalculator()
   {
      return new Add();
   }
}
public class SubFactory:ICalFactory
{
   public ICalculator GetCalculator()
   {
      return new Sub();
   }
}
public class MulFactory:ICalFactory
{
   public ICalculator GetCalculator()
   {
      return new Mul();
   }
}
public class DivFactory:ICalFactory
{
   public ICalculator GetCalculator()
   {
      return new Div();
   }
}
代码语言:javascript
复制
publci static void Main(string[]args)
{
    Console.WriteLine("请输入操作数1");
    double d1=Convert.Todouble(Console.ReadLine());
    Console.WriteLine("请输入操作数2");
    double d2=Convert.Todouble(Console.ReadLine());
    Console.WriteLine("请输入操作符");
    string oper=Console.ReadLine();
    ICalFactory calFac=null;
    switch(oper)
    {
    case"+":
        calFac=new AddFactory();
        break;
      case"-":
        calFac=new SubFactory();
        break;
      case"*":
        calFac=new MulFactory();
        break;
      case"/":
        calFac=new DivFactory();
        break;      
    }
    ICalculator cal=calFac.GetCalculator();
    double ret=cal.GetResult(d1,d2);
    Console.ReadKey();
}

三、工厂方法设计模式与反射

switch...case... 运算符和具体工厂对象之间的对应关系

代码语言:javascript
复制
public interface ICalculator   
{
    public 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;
    }
}

代码语言:javascript
复制
//1.使用Attribute给代码贴狗皮膏药
public class OperToFactory:Attribute
{
    public string Oper{get;}//因为值是我们直接写好,贴到类上,不需要set方法来赋值
    public OperToFactory(string s)
    {
       this.Oper=s;
    }
}
//2,程序运行后,拿到这段关系,并且返回响应的对象
public class ReflectionFactory
{
   //根据用户输入(操作符),返回一个对象
   Dictionary<string,ICalFactory> dic=new Dictionary<string,ICalFactory> ();
   public ReflectionFactory()
   {
      //1。拿到当前运行的程序集
      Assembly assembly=Assembly.GetExecutingAssembly();
      //AddFactory SubFactory MulFactory DivFactory
      foreach(var item in assembly.GetTypes())
      {
         //item 是ICalFactory类型的类,且不是接口
         if(typeof(ICalFactory).IsAssignableFrom(item)&&!item.IsInterface)
         {
            OperToFactory otf=item.GetCustomAttribute<OperToFactory>();
            if(otf.Oper!=null)
            {
               //给键值对集合赋值
               dic[otf.Oper]=Activator.CreateInstance(item) as IcalFactory;
            }
         }
      }      
   }
   public ICalFactory GetFunc(string s)
   {
      if(dic.ContainsKey(s))
      {
         return dic[s];
      }   
      return null;   
   }   
}

public interface ICalFactory
{
   ICalculator GetCalculator();
}

[OperToFactory("+")]
public class AddFactory:ICalFactory//细节依赖抽象
{
   public ICalculator GetCalculator()
   {
      return new Add();
   }
}

[OperToFactory("-")]
public class SubFactory:ICalFactory
{
   public ICalculator GetCalculator()
   {
      return new Sub();
   }
}

[OperToFactory("*")]
public class MulFactory:ICalFactory
{
   public ICalculator GetCalculator()
   {
      return new Mul();
   }
}

[OperToFactory("/")]
public class DivFactory:ICalFactory
{
   public ICalculator GetCalculator()
   {
      return new Div();
   }
}
代码语言:javascript
复制
publci static void Main(string[]args)
{
    Console.WriteLine("请输入操作数1");
    double d1=Convert.Todouble(Console.ReadLine());
    Console.WriteLine("请输入操作数2");
    double d2=Convert.Todouble(Console.ReadLine());
    Console.WriteLine("请输入操作符");
    string oper=Console.ReadLine();
    ReflectionFactory reff=new ReflectionFactory ();
    IcalFactory calFac=reff.GetFunc(oper);
    Icalculator cal=calFac.GetCalculator();
    double ret=cal.GetResult(d1,d2);
    Console.WriteLine(ret);
    //ICalFactory calFac=null;
    /****************************
    switch(oper)
    {
    case"+":
        calFac=new AddFactory();
        break;
      case"-":
        calFac=new SubFactory();
        break;
      case"*":
        calFac=new MulFactory();
        break;
      case"/":
        calFac=new DivFactory();
        break;      
    }
    ****************************/
    //ICalculator cal=calFac.GetCalculator();
    //double ret=cal.GetResult(d1,d2);
    Console.ReadKey();
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档