设计模式 ---- 简单工厂模式(一)

1、面向对象的思想

传统印刷术与活字印刷术,这就好像是面向过程和面向对象的思想,之前我们编写程序是从计算机的角度来进行编写程序,虽然,这样速度快,简洁优美,但是不容易维护,难复用,不好扩展,灵活性也不好。这就像一个刻好的印刷板一样,刷墨,放纸就行了,但是,这个板子只能做这一件事呀,

而面向对象就需要从用户的角度出发,要考虑多种情况,他们会改需求,加需求,减需求,就想一个刻好的模板,发现字不对,要改个字,加个字,或减个字,将字的顺序从左到右变成从上到下,不能每次都要动整体对吧,因为万事万物都是变化的,这就像活字印刷术一样,刻好的每个字都有用,这次不到下次也能用,可以重复使用,修改的话只需要动某个字就行了,扩展的话只需要增加某个字在放进去就行了,变换顺序,也只要将字的顺序调整一下,灵活性大大增加,而且以后维护的话也容易维护,因为直接看一段的话,肯定没有将这一段分成不同的几块后更容易理解。而且我的记忆力也不怎么出众。

将上面的话专业点就是,面向过程思想编写的程序耦合度很高,他的每一块都和整体密不可分,牵一发而动全身,将一件事分成先后顺序后,然后使用函数一个一个依次调用。

而面向对象,通过封装、继承、多态把程序的耦合度降低,在结合设计模式使程序更加的灵活,容易修改,易于复用。

注意:复制与复用

复制的话,将原来的代码改个名字在增加一次,原来的代码做的还是原来的事,导致整体代码增加

复用的话,这段代码,都可以调用, 尽量避免含有重复的代码。

一个小例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace obgestu
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.Write("请输入数字A:");
                string strNumberA = Console.ReadLine();
                Console.Write("请选择括号中的运算符号(+,-,*,/):");
                string strSymbol = Console.ReadLine();
                Console.Write("请输入数字B:");
                string strNumberB = Console.ReadLine();
                string strResult = string.Empty;
                switch (strSymbol)
                {
                    case "+":
                        strResult = Convert.ToString(Convert.ToDouble(strNumberA) + Convert.ToDouble(strNumberB));
                        break;
                    case "-":
                        strResult = Convert.ToString(Convert.ToDouble(strNumberA) - Convert.ToDouble(strNumberB));
                        break;
                    case "*":
                        strResult = Convert.ToString(Convert.ToDouble(strNumberA) * Convert.ToDouble(strNumberB));
                        break;
                    case "/":
                        if (strNumberB != "0")
                        {
                            strResult = Convert.ToString(Convert.ToDouble(strNumberA) / Convert.ToDouble(strNumberB));
                        } else
                        {
                            strResult = "除数不能为0";
                        }
                        break;

                    default:
                        Console.WriteLine("请输入正确的符号!");
                        break;
                }
                Console.WriteLine("结果是:" + strResult);
                Console.ReadLine();
                

            }
            catch (Exception ex)
            {
                Console.WriteLine("您输入的有错,请根据提示输入!:"+ex.Message);
                Console.ReadLine();
            }

        }
    }
}

2、封装

 将业务逻辑与界面逻辑分开,让他们的耦合度下降

运算类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace obgestu
{
    class Symbol
    {
        public static string GetResult(double numberA,double numberB,string strSymbol)
        {
            string result = string.Empty;
            switch (strSymbol)
            {
                case "+":
                    result =Convert.ToString(numberA + numberB);
                    break;
                case "-":
                    result = Convert.ToString(numberA - numberB);
                    break;
                case "*":
                    result = Convert.ToString(numberA * numberB);
                    break;
                case "/":
                    if (numberB == 0)
                    {
                        result = "除数不能是0!";
                    }
                    else
                    {
                        result = Convert.ToString(numberA / numberB);
                    }
                    break;
                default:
                    result = "请输入正确的符号!";
                    break;
            }

            return result;

        }
    }
}

客户端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace obgestu
{
    class InputText
    {

        static void Main(string[] args)
        {
            try
            {
                Console.Write("请输入数字A:");
                string strNumberA = Console.ReadLine();
                Console.Write("请选择运算符号(+、-、*、/):");
                string stSymbol = Console.ReadLine();
                Console.Write("请输入数字B:");
                string strNumberB = Console.ReadLine();
                string strResult = string.Empty;
                strResult = Symbol.GetResult(Convert.ToDouble(strNumberA), Convert.ToDouble(strNumberB), stSymbol);
                Console.WriteLine("结果是:"+strResult);
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("您输入的不对:" + ex.Message);
            }
        }
    }
}

虽然可以满足但是只用到的封装,而且分的还不够开可以再次修改为

 

3、封装、继承、多态

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//运算数
namespace obgestu.model
{
   public  class Operands
    {
        private double _numberA = 0;
        private double _numberB = 0;
        public double NumberA
        {
            get { return _numberA; }
            set { _numberA = value; }
        }
        public double NumberB
        {
            get { return _numberB; }
            set { _numberB = value; }
        }
        //实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。
        public virtual double GetResult()
        {
            double result = 0;
            return result;
        }
    }
}

继承

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using obgestu.model;

namespace obgestu.service
{
    //加法类  继承 运算基类
    class OperationAdd : Operands
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA + NumberB;
            return result;
        }
    }
    //减法类 继承 运算基类
    class OperationSubtraction : Operands
    {
        //重写虚方法
        public override double GetResult()
        {
            double result = 0;
            result = NumberA - NumberB;
            return result;
        }
    }
    //乘法类 继承 运算基类
    class OperationMultiplication : Operands
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA * NumberB;
            return result;
        }
    }
    //除法类 继承 运算基类
    class OperationDivide : Operands
    {
        public override double GetResult()
        {
            double result = 0;
            if (NumberB == 0)
            {
                throw new Exception("除数不能为0!");
            }else
            {
                result = NumberA / NumberB;
            }
            return result;
        }
    }

}

 

4、简单工厂模式

如何优雅的实例化对象,使用一个单独的类来创造实例的过程,称为工厂

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using obgestu.model;
using obgestu.service;

namespace obgestu
{
    class OperationFactory
    {
        public static Operands createOperateFactory(string symbol)
        {
            Operands operands = null;
            switch (symbol)
            {
                case "+":
                    operands = new OperationAdd();
                    break;
                case "-":
                    operands = new OperationSubtraction();
                    break;
                case "*":
                    operands = new OperationMultiplication();
                    break;
                case "/":
                    operands = new OperationDivide();
                    break;
                default:
                    throw new Exception("请正确输入符号!");
                    //break;
            }


            return operands;
        } 

    }
}

只需要输入运算符号,工厂就可以实例化合适的对象,通过多态,将计算的结果返回父类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using obgestu.service;
using obgestu.model;


namespace obgestu
{
    class Calculator
    {
        static void Main(string[] args)
        {
            Operands operand;
            //借助工厂进行实例化相应的对象
            operand = OperationFactory.createOperateFactory("==");
            operand.NumberA = 1;
            operand.NumberB = 0;
            double result = operand.GetResult();
            Console.WriteLine("结果:" + result);
            Console.ReadLine();
        }
    }
}

 

使用vs 生成类图:

 

posted on 2020-07-02 22:39  obge  阅读(275)  评论(0编辑  收藏  举报