简述设计模式六大原则

设计模式六大原则,包括:

1.单一职责原则

2.里氏替换原则

3.依赖倒置原则

4.接口隔离原则

5.迪米特法则原则

6.开闭原则

下面分别来解释一下这六大原则。

单一职责原则:

单一职责原则主要是对类库与类库、类与类以及方法与方法之间的功能职责的描述——(个人理解为封装)

第一是类库的单一职责,从系统的解决方案分析,最传统的三层模式,UI层、业务逻辑层以及数据访问层,三层可以代表三个类库(dll)。每一个类库的职责分明,UI层用于管理和实现UI的实现,业务逻辑层用于管理和实现系统业务逻辑,数据访问层用于管理和实现数据库链接和访问。

第二是类的单一职责,系统每个类的理想状态是只描述一类的情况,例如Student类,只要描述Student属性,字段,方法等,不应该处理School或其他类的功能等,这样就可以避免在修改Student类时影响到School类的功能,或者是修改School类时影响到Student类的情况。

第三是方法的单一职责,例如Student类中有新增方法和修改方法,有的人比较喜欢写成一个方法,根据传入的某个参数来区分是新增还是更新,这就违背了单一职责,当你修改新增逻辑时,有可能会影响到修改逻辑,比如修改新增逻辑后,在某一步异常了,就会影响到你的更新逻辑,所以应该写新增和修改两个方法,把它们区分开,它们本来就是不相干的方法,不一样写在一起。总个来说,一个方法,最好是只能做一件事,让方法最小化,方便后期的维护。

里氏替换原则:

里氏替换原则,任何使用父类的地方都可以用子类来代替——(个人理解为继承和多态)

下面用一段代码来解释一下,相对来说会直观一点:

下面的Chain类的实例,都可以用GuangDong类的实例来代替,子类都是可以替代父类的,但父类不能代替子类。

 
  
{
                var chain = new Chian();
                chain.SayHi();
                chain = new GuangDong();
                chain.SayHi();
 }
 public abstract class Human
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public abstract void SayHi();
    }

    public class Chian:Human
    {

        public override void SayHi()
        {
            Console.WriteLine(string.Format("你好!!我是{0}",Name));
        }
    }

    public class GuangDong : Chian
    {
        public void EatSomething()
        {
            Console.WriteLine("广东人喜欢吃东西!!");
        }
    }



依赖倒置原则:

程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了模块与模块间的耦合。——(个人理解为模块之间降低耦合度)

下面用图形来解释一下:左边是经典三层架构的简单示意图,UI层依赖业务逻辑层,业务逻辑层依赖数据访问层,属于高耦合,根据项目需求,如果替换掉数据访问层,那么整个业务逻辑层就要重写,对于一个公司项目了说,需要花费很大了人力和物力,很多公司都不愿意看到这样的情况,所以我们提倡额高内聚低耦合,为了实现低耦合,就出现了下图右边架构图,让项目UI层、业务逻辑层、数据访问层去依赖抽象,依赖接口来开发,即第三方容器(这种容器可以自己开发);当你要替换数据访问层时,对业务逻辑层来说完全不影响,替换了业务逻辑层,对UI层来说也不受影响的,实现了解耦。从层与层直接高度耦合变成了相互之间互不影响,降低了维护和修改成本。但是UI层、业务逻辑层和数据访问层还是依赖于抽象、接口,也是需要维护他们之间的关系,只不过是维护成本降低了,可以更灵活的维护,因此依赖关系发生了改变,实现的了依赖倒置。

简述设计模式六大原则_第1张图片

接口隔离原则:

客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上-(个人理解为,类只继承自己需要的功能的接口,自己不要的功能,不要继承)

比如你定义数据库访问的接口(IDBAccess),文件读取的接口(IFileRead),你实现一个数据库访问的类DBAccess,DBAccess类只要继承实现IDBAccess接口即可,不要继承IFileRead接口。

接口定义功能时,也不宜太多,也不宜太少;例如定义一个手机接口Iphone,Iphone接口包括:

public interface Iphone
    {
        void Call();

        void Move();

        void Music();

        void Game();

        void Pay();

    }
假如Ipad只有Move、Music和Game的功能,这时Ipad就不能继承实现Iphone接口,应该把Iphone接口拆成两个两个接口,包含上面的上的所有的功能,尽可能的细化接口和实现接口,也能太细化接口,最好不要一个接口只有一个功能的设计,这样接口就太多,不易管理。


迪米特法则原则:

最少知道原则,即一个对象应当对其他对象有尽可能少的了解,不要和陌生人讲话,只和自己的朋友说话。

例如下图,部门总监,部门经理,项目经理,开发都各自代表一个类,部门总监管部门经理,部门经理管项目经理,项目经理管开发,他们不要跨级访问,这就是迪米特法则,尽可能少的访问与自己没有直接关系的类。

简述设计模式六大原则_第2张图片

代码例子:

类与类之间关系层级分明,不出现跨级访问和操作

public class Staff
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public int Gender { get; set; }
    }
    public class Majordomo: Staff
    {
        public Manager Underling { get; set; }

        public void Work()
        {
            Console.WriteLine($"部门经理{Underling.Name}和部门总监{this.Name}汇报工作");
        }
    }

    public class Manager: Staff
    {
        public ProjectManager Underling { get; set; }

        public void Work()
        {
            Console.WriteLine($"和项目小组组长{Underling.Name}计划排期项目时间进度");

        }
    }

    public class ProjectManager: Staff
    {
        public Development Underling { get; set; }
        public void Work()
        {
            Console.WriteLine($"给小组开发人员安排工作,被安排人名称为:{Underling.Name}");

        }
    }

    public class Development: Staff
    {
        public void Develop()
        {
            Console.WriteLine("软件开发");
        }
    }

开闭原则:

对于扩展开放,对修改关闭,意味着行为是可扩展的,当我们项目中的需求发生改变是,我们可以对现有模块进行扩展,不修改原有逻辑的情况下,实现新增需求的功能。

个人觉得开闭原则是设计模式六个原则中最虚的一个,基本是一个理想化的原则,也是最重要的一个原则,在我遇到的项目中,基本上很少能够完全符合这个设计原则。


总结:

设计模式的六大原则,纯属是我个人的理解,并且在实际工作项目中,很少有项目能够全部都遵循这六大原则,都有一定的取舍,要看具体的项目做相应的取舍和更偏向于哪个原则,类似于倾斜式的满足要求。











你可能感兴趣的:(设计模式)