c# 之简单工厂模式

2021-05-04 15:29

阅读:521

标签:try   设计   mes   存储   数字   param   编写   扩展   err   

简单工厂模式

前言:简单工厂模式也是我们编程中经常用到和非常常见的一种设计模式。通过一些书籍和视频的观看后,自己也是写一篇博客来加深自己的理解,已备复习之用。

一:那么我们先来看一个例子:我们如何实现一个简单的计算器的功能呢??首先我们先来看运算类,代码如下:

    /// 
    /// 运算类
    /// 
    public class Operation
    {
        /// 
        /// 得到结果的方法
        /// 
        /// 输入的数字a
        /// 输入的数字b
        /// 输入的指令
        /// 返回结果
        public static double GetResule(double numberA, double numberB, string operate)
        {
            double result = 0d;
            switch (operate)
            {
                case "+":
                    result = numberA + numberB;
                    break;
                case "-":
                    result = numberA - numberB;
                    break;
                case "*":
                    result = numberA * numberB;
                    break;
                case "/":
                    result = numberA / numberB;
                    break;
            }
            return result;
        }
    }

 


客户端代码如下:

class Program
    {
        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();
                string strResult = Convert.ToString(Operation.GetResule(Convert.ToDouble(strNumberA), Convert.ToDouble(strNumberB), strOperate));
                Console.WriteLine("结果是:{0}", strResult);
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine("你输入的有误:" + ex.Message);
            }
        }
    }

这时候我们需要考虑一个问题:假如在我在增加一个开根运算,那么我们如何修改呢??问题是:我们要加一个开根的运算,需要让加减乘除都参与进来进行编译。比如我们来打一个比方:如果现在公司要求你为公司的薪资管理系统进行维护,原来只有技术人员,市场的销售人员,经理,这个时候我们现在在加入一个兼职工作人员的工资,按照我们现在的这种写法,公司就得需要把包含前三种的运算类的编码都给你,这样的话是不是显得有点不合适呢。

在这个时候我们可不可以这样做:我们应该把加减乘除类全部都分离开来,我们修改其中的一个,都不会影响到其他的运算类。

这个时候面向对象的思想就显得尤为重要了:我们可以使用封装 继承 多态可以把程序的耦合度降低,并且使用设计模式使得程序更加的灵活,容易修改,并且易于复用,我们总结的四个面向对象的好处是:(1)可维护 (2) 可复用  (3)可扩展 (4)灵活性好。    

这时候我们考虑应该如何做呢?

既然我们决定把加减乘除都分离开来都写成一个单独的类来进行存储。我们需要考虑他们这四个类中都需要什么(或者有什么共同的东西)。

1.他们四个类都需要有两个数字(NumberA和NumberB)。

2.他们都需要一个得到计算之后的结果。

这样的话我们可以声明一个抽象的父类已供子类继承使用,详细代码如下:

 

    /// 
    /// 抽象方法
    /// 
    public abstract class CalFather
    {
        //数字一
        private double _numberOne;
        //属性用来保护字段
        public double NumberOne
        {
            get
            {
                return _numberOne;
            }

            set
            {
                _numberOne = value;
            }
        }
        //数字二
        private double _numberTwo;
        //属性的设置用来保护字段
        public double NumberTwo
        {
            get
            {
                return _numberTwo;
            }

            set
            {
                _numberTwo = value;
            }
        }
        //抽象的方法
        public abstract double GetResult();
        /// 
        /// 父类自己的构造函数,进行传值使用。
        /// 
        /// 第一个数字
        /// 第二个数字
        public CalFather(double n1, double n2)
        {
            this.NumberOne = n1;
            this.NumberTwo = n2;
        }
    }

 


这样的话我们就可以在子类中重写父类的抽象的方法了。详细代码如下:

 

 

    /// 
    /// 加法
    /// 
    public class Jia : CalFather
    {
        //继承父类得到父类的字段
        public Jia(double n1, double n2) : base(n1, n2)
        {

        }
        /// 
        /// 方法的重写
        /// 
        /// 总和
        public override double GetResult()
        {
            return this.NumberOne + this.NumberTwo;
        }
    }
    /// 
    /// 减法
    /// 
    public class Jian : CalFather
    {
        public Jian(double n1, double n2) : base(n1, n2)
        {

        }
        /// 
        /// 方法的重写
        /// 
        /// 总和
        public override double GetResult()
        {
            return this.NumberOne - this.NumberTwo;
        }
    }
    /// 
    /// 乘法
    /// 
    public class Cheng : CalFather
    {
        public Cheng(double n1, double n2) : base(n1, n2)
        {

        }
        /// 
        /// 方法的重写
        /// 
        /// 总和
        public override double GetResult()
        {
            return this.NumberOne * this.NumberTwo;
        }
    }
    /// 
    /// 除法
    /// 
    public class Chu : CalFather
    {
        public Chu(double n1, double n2) : base(n1, n2)
        {

        }
        /// 
        /// 方法的重写
        /// 
        /// 总和
        public override double GetResult()
        {
            return this.NumberOne / this.NumberTwo;
        }
    }

 


当编写完上面的代码之后,我们该考虑如何的实例化对象的问题了。这时候我们的“简单工厂模式”就派上用场了。

简单工厂的最主要的一点是:返回父类。

为什们要返回父类呢?这里用到了里式转换的思想。

(1):子类可以赋值给父类。

(2):如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。

代码如下:

        /// 
        /// 简单工厂的核心
        /// 
        /// 输入的运算符
        /// 第一个数字
        /// 第二个数字
        /// 进行父类的重写的方法
        public static CalFather GetCal(string opera, int n1, int n2)
        {
            CalFather cal = null;
            switch (opera)
            {
                case "+":
                    cal = new Jia(n1, n2);
                    break;
                case "-":
                    cal = new Jian(n1, n2);
                    break;
                case "*":
                    cal = new Cheng(n1, n2);
                    break;
                case "/":
                    cal = new Chu(n1, n2);
                    break;
            }
            return cal;
        }
    }

这样的话我们在增加各种复杂的运算,比如平方根,立方根,这个时候我们只需要添加相应的子类在继承父类就可以了,在修改共产添加分支就行了。而我们之前实现的代码没有进行任何的修改。这也体现了面向对象的好处。

好了,本次的讲解就到这里了,大家有什么问题可以积极的留言。谢谢大家。

 

c# 之简单工厂模式

标签:try   设计   mes   存储   数字   param   编写   扩展   err   

原文地址:http://www.cnblogs.com/MoRanQianXiao/p/7712720.html


评论


亲,登录后才可以留言!