zoukankan      html  css  js  c++  java
  • 面向对象原则之一 依赖倒置原则

    前言

    面向对象有人分为五大原则,分别为单一职责原则、开放封闭原则、依赖倒置原则、接口隔离原则、里氏替换原则。

    也有人分为六大原则,分别为单一职责原则、开放封闭原则、依赖倒置原则、接口隔离原则、里氏替换原则、迪米特法则。

    现在我们来介绍依赖倒置原则

    依赖倒置原则

    1)概念

    a.高层模块不应该依赖于底层模块,两者应该依赖于其抽象。

    b.抽象不应该依赖具体实现,具体实现应该依赖抽象。

    上面2点是依赖倒置原则的概念,也是核心。主要是说模块之间不要依赖具体实现,依赖接口或抽象。

    其实依赖倒置原则的核心思想是面向接口编程。

    2)例子

    依赖倒置原则其实也没什么可以说的,下面我们来举个例子吧。

    比如,学生看语文书。我们就实现这两个类,一个是学生,一个是语文书。学生依赖于语文书,所以语文书是学生的一个属性。

    UML图如下:

    image

    类如下。

    首先是学生Student类:

    public class Student
        {
    
            public void DoSomething(YuWenBook book)
            {
                book.LookYuWenBook();
            }
    
        }

    然后是语文书类YuWenBook类:

    public class YuWenBook
        {
    
            public void LookYuWenBook()
            {
                Console.WriteLine("看语文书");
            }
    
        }

    最后,我们开始调用:

    class Program
        {
            static void Main(string[] args)
            {
                YuWenBook book = new YuWenBook();
                Student student = new Student();
                student.DoSomething(book);
    
            }
        }

    以上程序都没有错,new一个语文的对象,然后new一个学生对象,最后把语文对象赋值到学生的book中。完成了学生看书。

    但是,这是不好扩展的,抛离了面向对象的低耦合,高内聚的思想。因为,如果,我们要添加学生看英语书,那怎么添加呢?

    首先,在Student类中添加方法DoSomething(EnglishBook book); 然后再实现EnghlishBook类的LookEnglishBook方法。

    最后调用,变成:

    static void Main(string[] args)
            {
                YuWenBook book = new YuWenBook();
                Student student = new Student();
                student.DoSomething(book);
    
                //学生看英语书
                EnglishBook englishBook = new EnglishBook();
                student.DoSomething(englishBook);
    
            }

    一看,就知道不好扩展。因为已经修改了Student类中代码(增加了方法)。怎么才算好扩展呢,那么要聊起与开闭原则有关系了。对修改关闭,对扩展开放。所以我们尽量的不要修改Student类中的代码。所以,我们增加一个接口,叫IBook:

    public interface IBook
        {
    
            void LookBook();
    
        }

    然后,英语、语文各自继承IBook:

        public class EnglishBook: IBook
        {
            public void LookBook()
            {
                Console.WriteLine("看英语书");
            }
    
        }
    
        public class YuWenBook:IBook
        {
    
            public void LookBook()
            {
                Console.WriteLine("看语文书");
            }
    
        }

    再修改一下Student的方法,接收IBook参数,变成:

    public class Student
        {
    
            public void DoSomething(IBook book)
            {
                book.LookBook();
            }
    
        }

    最后,看我们是怎么调用的:

    static void Main(string[] args)
            {
                IBook book = new YuWenBook();
                Student student = new Student();
                student.DoSomething(book);
    
                //学生看英语书
                book = new EnglishBook();
                student.DoSomething(book);
    
            }

    看看,是不是可以很方面的扩展? 为什么这样说呢?

    因为当我们再添加一个学生看数学书的时候,我们只需要添加一个数学书类来继承IBook,然后实现LookBook方法。最后我们用IBook对象来调用数学书类就可以了。可以看出,Student不用做任何修改,IBook也是。只需做相应的实现与调用即可。

    3)小结

    到此,介绍与例子到此结束了,我们可以看到面向对象的设计是多么的广、深。从一些小小的例子、甚至身边发生的事,都可以联想到面向对象的设计。要掌握面向对象,首先要掌握其原则。

    其他链接:

    开放封闭原则(开闭原则)

    单一职责原则

    依赖倒置原则

    接口隔离原则

    里氏替换原则

    迪米特法则

    此文转发,请注明出处,谢谢。

    可以关注本人的公众号,多年经验的原创文章共享给大家。

  • 相关阅读:
    Codeforces Round #588 (Div. 2) D Marcin and Training Camp
    DFS / BFS题目栏 (来自一个队友退役后,不得不,重拾图论的选手的叹息)
    Codeforces Round #588 (Div. 2) Anadi and Domino (dfs)
    Codeforces Round #585 (Div. 2) A,B,C,D
    【题解】牛客挑战赛32 (两道水题+一题矩阵快速幂)
    c/c++输入时间问题
    莫队 + 带修莫队
    hdu 5775 Bubble Sort (树状数组)
    UVALive 4329 Ping pong (树状数组)
    hdu 5754 Life Winner Bo(博弈)
  • 原文地址:https://www.cnblogs.com/alunchen/p/7110116.html
Copyright © 2011-2022 走看看