C# 丢弃工厂模式,反射方式实现计算器
来源:互联网 发布:淘宝买托福答案被骗 编辑:程序博客网 时间:2024/06/10 10:34
在学习设计模式的时候,其中有一种模式叫工厂模式,工厂模式里经典的案例就是设计一个计算器,在工厂模式里都是用swith() ... case ...来实例化类。并调用类里的方法
例:
每添加一种计算方法,那就要在swith() ... case ...里实例化该类,这样有一个步骤忘了,就计算不出来结果
所以我就想要是只要类的名字,然后通过这个名字实例化类出来,然后再调用类里计算的方法,
这样的话,我就只需要编写类的计算方法,然后把这个类的类名告诉程序,程序在计算时,通过
用户输入的计算符号(如+,-,*,/,√)来进行选择用那个类进行计算,有了这个思路,但是这种方
法是否可行呢,有了反射,这个想法是肯定可以的,下面就是我用这种方式实的!
加法类
我这里用枚举去存,个人爱好!
结语:为什么要用反射,这样的好处就是我再添加其它运算类时,只需要继承BaseClass类,并自述自己是
用来做什么样的运算,即Symbol=“那种计算方式”,重写Calculation方法,并返回结果。实现计算类后,把
类名加 enum ClassName里面,就可以了,便于后期添加更多的计算类。
例:
switch (symbol) { case "+": bc = new Add(); bc.Calculation(num1,num2); break; case "-": bc = new Sub(); bc.Calculation(num1, num2); break; case "*": bc = new Mul(); bc.Calculation(num1, num2); break; case "/": bc = new Div(); bc.Calculation(num1, num2); break; default: bc = new BaseClass(); bc.Calculation(num1, num2); break; }
每添加一种计算方法,那就要在swith() ... case ...里实例化该类,这样有一个步骤忘了,就计算不出来结果
所以我就想要是只要类的名字,然后通过这个名字实例化类出来,然后再调用类里计算的方法,
这样的话,我就只需要编写类的计算方法,然后把这个类的类名告诉程序,程序在计算时,通过
用户输入的计算符号(如+,-,*,/,√)来进行选择用那个类进行计算,有了这个思路,但是这种方
法是否可行呢,有了反射,这个想法是肯定可以的,下面就是我用这种方式实的!
定义一个基类BaseClass,里面包含了计算的符号和计算的方法
class BaseClass { /// <summary> /// 符号 /// </summary> public string Symbol { get; set; } /// <summary> /// 计算方法 /// </summary> /// <param name="a">其中一个值</param> /// <param name="b">另一个值</param> /// <returns></returns> public virtual float Calculation(float a, float b) { return 0; } }接下来就是我们计算类,所有计算类都继承基类BaseClass
加法类
class Add : BaseClass { const string add = "+"; public Add() { Symbol = add; } public override float Calculation(float a, float b) { return a + b; } }减法类
class Sub : BaseClass { const string sub = "-"; public Sub() { Symbol = sub; } public override float Calculation(float a, float b) { return a - b; } }乘法类
class Mul : BaseClass { const string mul = "*"; public Mul() { Symbol = mul; } public override float Calculation(float a, float b) { return a * b; } }除法类
class Div : BaseClass { const string div = "/"; public Div() { Symbol = div; } public override float Calculation(float a, float b) { if (0 == b) { return 0; } return a / b; } }开方类
class Square:BaseClass { const string sub = "√"; public Square() { Symbol = sub; } public override float Calculation(float a, float b) { return (float)Math.Sqrt(a); } }定义好了计算类,现在要让程序知道,这些类叫什么名字,可以把它存在一个数组,链表,枚举里
我这里用枚举去存,个人爱好!
enum ClassName { Add, Sub, Mul, Div, Square }现在计算类有了,类名也有了,接下来就是要实例化这些类,那就得用反射的原理了
/// <summary> /// 实例化ClassName里Add、Sub、Mul、Div、Square运算类 /// </summary> /// <returns></returns> static List<object> InitBaseClass() { if (Enum.GetNames(typeof (ClassName)).Length == 0) return null; //定义BaseClass实例化 List<object> bsList = new List<object>(); // 获取当前方法的命名空间 string nameSpace = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace; //实例化ClassName里Add、Sub、Mul、Div、Square运算类 foreach (var name in Enum.GetNames(typeof (ClassName))) { Type type = Type.GetType(nameSpace + "." + name); //获取类型 bsList.Add(Activator.CreateInstance(type)); //根据类型创建实例 } return bsList; }类实例出来后,当我输入5+5时,程序就要自己去匹配加法类的计算方法,然后返回结果
/// <summary> /// 计算结果 /// </summary> /// <param name="bsObjects">有多少个运算类</param> /// <param name="symbol">什么符号</param> /// <param name="num1">计算的数字一</param> /// <param name="num2">计算的数字二</param> /// <returns></returns> static object CalcResult(List<object> bsObjects, string symbol, float num1, float num2) { if (bsObjects.Count == 0 || string.IsNullOrEmpty(symbol)) return null; object result = null; foreach (var intance in bsObjects) { //获取的值是什么符号 var symbolValue = intance.GetType().GetProperty("Symbol").GetValue(intance, null); //要调用那个运算类的方法 if (Convert.ToString(symbolValue) == symbol) { //调用类里的Calculation方法所获得的返回值 result = intance.GetType().GetMethod("Calculation").Invoke(intance, new object[] {num1, num2}); } } if (result == null) return "没有正确的运算符!"; return result; }最后就是调用
static void Main(string[] args) { //存储实例化的计算类,只实例化一次 List<object> bsObjects = InitBaseClass(); //开线程调用计算方法 //new Thread(() => //{ // Console.WriteLine(CalcResult(bsObjects, "+", 5, 80)); //}) //{IsBackground = true}.Start(); //调用计算方法 object result = CalcResult(bsObjects, "√", 3, 8); Console.WriteLine(result); Console.ReadKey(); }
结语:为什么要用反射,这样的好处就是我再添加其它运算类时,只需要继承BaseClass类,并自述自己是
用来做什么样的运算,即Symbol=“那种计算方式”,重写Calculation方法,并返回结果。实现计算类后,把
类名加 enum ClassName里面,就可以了,便于后期添加更多的计算类。
阅读全文
0 0
- C# 丢弃工厂模式,反射方式实现计算器
- C#简单工厂设计模式实现计算器
- 工厂方法模式 实现计算器
- 简单工厂模式 ,策略模式 实现计算器
- 利用反射实现工厂模式.
- java反射实现工厂模式
- 反射实现简单工厂模式
- 工厂模式例子之计算器的实现
- java简单工厂设计模式实现计算器
- 基于C#反射机制的工厂模式
- c#设计模式--工厂方式模式
- 工厂模式及使用反射实现工厂模式
- C++模拟反射实现工厂模式
- 简单的用反射实现工厂模式
- 利用反射机制实现工厂模式
- 计算器 --- 简单工厂模式
- 简单工厂模式-计算器
- 简单工厂模式计算器
- promise 和async await
- 数据结构思维 第六章 树的遍历
- datacleaner默认日志配置.xml
- 零基础学习GitHub桌面版-5 github的使用技巧
- Source for FrontEnd
- C# 丢弃工厂模式,反射方式实现计算器
- Android ADB命令大全(通过ADB命令查看wifi密码、MAC地址、设备信息、操作文件、查看文件、日志信息、卸载、启动和安装APK等)
- x-pack安装结合elasticsearch5.4和kibana5.4
- 【道路路网(公路、铁路)、水系、建筑物轮廓、地名等等】
- 字符串左移
- RabbitMQ核心概念篇
- 剑指offer(纪念版) 面试题3:二维数组中的查找
- Github Pages搭建个人站点和项目站点
- Activiti之流程通过、驳回、会签、转办、中止、挂起等核心操作封装(Activiti5.9)