一:面向对象与面向过程

提到设计模式的好处,不得不提到面向对象编程与面向过程编程
话说很久以前,在中国的古代只有刻版印刷,有一次一位君王让工匠在石板上刻上"对酒当歌,人生真爽"这几个字,但刻出来君王看后觉得不妥认为应该改成"对酒当歌,人生几何",于是工匠重新刻板,之前刻上"对酒当歌,人生真爽"的板子就毫无用处了
当很多年后有了活字印刷后,每个字可以单独刻板,当需要更改时,则只需替换指定的字即可,实在妙哉
我们可以将最初的刻版印刷比作面向过程编程,把活字印刷比作面向对象编程,通过上面的例子就可以比较出面向对象编程比面向过程编程优势的地方:
——当需要更改时,则只需替换指定的字即可。可维护
——替换的字并非毫无用处,可以用于之后的印刷使用。可复用
——如果要加字,只需另刻字加入即可。可扩展
——字的排列有可能是竖排有可能是横排,此时只需将活字移动就可做到满足排列的需求。灵活性好

设计模式笼统来说就是通过封装、继承、多态把程序的耦合度降低,刻版印刷的问题就在于把所有的字都刻在同一版面上造成耦合度太高,用设计模式能够让程序更加的灵活,容易修改和扩展,并且易于复用
通过不断的探索和学习,设计模式可以让你找到封装变化,对象间松散耦合,面向接口编程的感觉,从而设计出易维护,易扩展,易复用,灵活性好的程序

如今再来看四大发明,火药、指南针、造纸术都是从无到有,是从未知到发现的伟大发明,而活字印刷仅仅是从刻版印刷到活字印刷的一次技术上的进步,但这却是人类思想的进步,将面向过程的思想跨越到了面向对象的思想


二:从代码中体会面向对象的优势

例如现在需要写一个模拟计算器的程序,实现加减乘除运算的功能

下面是面向过程的写法:

using System;

public class MainClass
{
    public static void Main()
    {
        Console.Write("输入第一个数字:");
        double num1 = double.Parse(Console.ReadLine());
        Console.Write("输入第二个数字:");
        double num2 = double.Parse(Console.ReadLine());
        Console.Write("输入运算符号(+ - * /):");
        string _operator = Console.ReadLine();
        double result = 0;
        switch (_operator)
        {
            case "+":
                result = num1 + num2;
                break;
            case "-":
                result = num1 - num2;
                break;
            case "*":
                result = num1 * num2;
                break;
            case "/":
                result = num1 / num2;
                break;
        }
        Console.WriteLine("结果:" + result);
    }
}

对于一名编程新手,难免会碰到问题就直觉地用计算机能够理解的逻辑去描述和表达求解的过程,首先输入两个数字,然后根据不同的符号选择运算方式,最终得到结果,这种思路本身没有错,但这种面向过程的思想会导致编写出的程序不易维护,不易扩展,不易复用,要使程序易维护,易扩展,易复用,则需要灵活运用面向对象的三大特性:封装,继承,多态

下面是面向对象的写法:

using System;

public class MainClass
{
    public static void Main()
    {
        IOperator o = new Sub();
        o.num1 = 1;
        o.num2 = 2;
        double result = o.GetResult();
        Console.WriteLine(result);
    }
}

public class IOperator
{
    public double num1, num2;
    public virtual double GetResult()
    {
        return num1 + num2;
    }
}
public class Add : IOperator
{
    public override double GetResult()
    {
        return num1 + num2;
    }
}
public class Sub : IOperator
{
    public override double GetResult()
    {
        return num1 - num2;
    }
}

假如现在需要增加一个取余的运算,则只需要增加一个取余的类继承Operator类即可,不需要对其他类进行修改