面向对象程序设计(Object Oriented Programming)的三大特性,六大原则

三大特性

封装、继承、多态性

拿简单工厂模式举例:

namespace DesignMode_01
{

    // 计算基类
    public class Operation
    {
        private double _numberA = 0;
        private double _numberB = 0;

        public double NumberA { get => _numberA; set => _numberA = value; }

        public double NumberB { get => _numberB; set => _numberB = value; }

        public virtual double GetResult()
        {
            double result = 0;
            return result;
        }
    }


    // 加法类
    public class OperationAdd : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA + NumberB;
            return result;
        }
    }

    // 减法类
    public class OperationSub : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA - NumberB;
            return result;
        }
    }

    // 工厂类:生产不同类的实例化对象
    public class OperationFactory
    {
        public static Operation CreateOperate(string operate)
        {
            Operation oper = null;
            switch (operate)
            {
                case "+":
                    oper = new OperationAdd();
                    break;
                case "-":
                    oper = new OperationSub();
                    break;
            }
            return oper;  
        }
    }

    // 当编译器遇到方法调用时,它首先在类型的实例方法中查找匹配项。如果找不到匹配项,它将搜索为该类型定义的所有扩展方法,并绑定到找到的第一个扩展方法。
    public static class MyExtensions
    {
        public static int Count(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' },
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }
    // 操作界面类
    class Program
    {
        static void Main(string[] args)
        {
            Operation operation;
            operation = OperationFactory.CreateOperate("+");
            operation.NumberA = 1;
            operation.NumberB = 2;
            double result = operation.GetResult();

            // 调用扩展方法
            string s = "Hello Extension Methods";
            s.Count();
        }
    }
}

封装:创建计算基类、工厂类和界面类让业务逻辑与界面逻辑分开,让它们之间的耦合度下降。

继承:加法减法类派生计算基类。

多态性:定义GetResult()虚方法,让派生类对同一个方法产生不同实现。多态性的具体实现包括重载和重写。

六大原则

单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。
比如:

  • 你把业务逻辑、数据库访问的sql语句什么都放在一个控制器里,这就意味着,无论什么需求要来,你都需要更改这个控制器,这其实是很糟糕的,维护麻烦,复用不可能,也缺乏灵活性。这个时候就可以把程序分为服务层、仓储层,服务层专门用来处理业务逻辑,仓储层专门用处理数据库访问的sql语句。
  • boss直聘前端页面一个搜索文本框,可以让你选择不同行业、不同月薪的分类按钮,按分类进行检索,这也是体现了单一职责思想。
  • 修电脑,显然内存坏了,不应该成为更换CPU的理由,他们各自的职责时明确的。当然,软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责,就应该考虑类的职责分离。

开发-封闭原则:就是软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。即面对需求,对程序的改动是通过增加新代码进行,而不是更改现有的代码。但是,绝对的对修改关闭是不可能的。在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发送的同类变化。
例如:

  • 把一个加法程序,都在一个client类中完成,如果要加一个减法功能,增加功能就需要修改原来的这个类,这就违背了开放-封闭原则。可以通过增加一个抽象的运算类,通过一些面向对象的手段,如继承、多态等来隔离具体加法、减法与client耦合。如果又要增加除法功能,你就不需要再去更改client以及加法减法的类了,而是增加乘法和除法子类就可。
  • 中国的一国两制思想,原有的中国社会主义制度不能修改,为了回归大局,通过增加一种制度又何尝不可。
  • C# 中的扩展方法,你不能修改微软的源码,但是微软给你提供了扩展方法,你可以通过新增扩展方法来实现需求。
  • 电脑内存不够只要插槽足够就可以添加,硬盘不够可以用移动硬盘等。

依赖倒转原则:说白了就是针对接口编程,不要对实现编程。
例如:

  • 我们的服务层、仓储层都是针对接口编程。只要仓储层接口不变,换任何数据库,都不影响服务层的业务逻辑。

里氏替换原则:子类型必须能够替换掉他们的父类型。只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能正真被复用,而子类也能够在父类的基础上增加新的行为。
例如:

  • 为什么要单独在仓储层来引入通用的ORM持久化接口,是因为,降低耦合,如果以后想要换成EF或者Deper,只需要修改Repository具体的实现类就行了,其他都不需要修改。

接口隔离原则: 客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。根据接口隔离原则,当一个接口太大时,我们需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。

迪米特法则:如果两个类不必彼此直接通信,那么这两个类就不要应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。首先强调的前提是在类的结构设计上,每一个类都应当尽量降低成员的访问权限,也就是说,一个类包装好自己的private状态,不需要让别的类知道的字段或行为就不要公开。根本思想是强调了类之间的松耦合。
例如:

  • IT部是抽象的,哪怕里面的人离职换了新人,我的电脑出问题了也还是可以找IT部解决,而不需要认识其中的同事,纯靠关系帮忙了。就算需要认识,我也只要认识IT部的主管就可以了,由他来安排工作。

你可能感兴趣的:(c#)