设计模式笔记(1)简单工厂模式

发布于:2025-07-21 ⋅ 阅读:(21) ⋅ 点赞:(0)

最近在看程杰的《大话设计模式》,在这里做一点笔记。

书中主要有两个角色:
小菜:初学者,学生;
大鸟:小菜表哥,大佬。
也按图中的对话形式

01 简单工厂模式

要求:使用c++、Java、C#或VB.NET任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果。
小菜的代码:
小菜的代码
大鸟指出部分问题:

  1. A, B, C, D 这样的命名不规范;
  2. if的判断分支,逻辑有误,且未考虑除数输入为0/输入为字符非数字等等。

小菜对代码进行修改:
修改后的代码

修改后的逻辑基本没有问题了,但是并没有面向对象。
如何设计出容易维护,容易扩展,又容易复用的计算器程序呢?
程序要避免重复。
小菜:那就是分类,将计算和显示分开?
大鸟:准确说,是让业务逻辑与界面逻辑分开,让它们之间的耦合度下降。只有分离开,才可以达到容易维护或扩展。

接下来,小菜重新进行了尝试:
运算类:
运算类
main函数:

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 = "";
        strResult = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumberA),
        Convert.ToDouble(strNumberB), strOperate));
        Console.WriteLine("结果是:" + strResult);
        Console.ReadLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine("您的输入有错:" + ex.Message);
    }
}​​

目前,无论在windows,还是在web,手机端都可以在需要运算时使用上面运算类的定义。
这里使用到的是“面向对象”的封装。

提问:如何更灵活的修改和扩展代码呢?比如,现在希望增加一个开根号(sqrt)的运算。
小菜:直接修改Operation类?
大鸟:但问题是,要加一个平方根运算,却需要让加减乘除的运算都得来参与编译。而且还可能让原有的运行良好的功能代码产生了变化,这个风险太大了

因此,需要尽量把加减乘除等运算分离,修改其中一个不影响其他
小菜进行新尝试:

operation运算类:

public class Operation
{
    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;
    }
}​​

两个Number属性,主要用于计算器的前后数,然后有一个虚方法GetResult(),用于得到结果。

加减乘法类:
加减乘法类
加减乘除都写成了运算类的子类,继承它后,重写了GetResult()方法,这样如果要修改任何一个算法,就不需要提供其他算法的代码了。
但是,如何让计算器知道我是希望用哪一个算法呢?

考虑用一个单独的类来做这个创造实例的过程,这就是“工厂”

进行如下设置:
实例化

此时,只需要输入运算符号,工厂就实例化出合适的对象。

一个实例:

Operation oper;
oper = OperationFactory.createOperate(“+”);
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();​​

此时,例如要修改加法运算,改OperationAdd即可。
如果需要增加各种复杂运算,增加相应的运算子类,并在switch中增加分支。


网站公告

今日签到

点亮在社区的每一天
去签到