面向对象程序设计思想——通俗版

面向对象程序设计思想

1 引言

设计模式是代码开发经验的总结,是针对特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的代码逻辑设计方案。就算你没有对象,也必须掌握面向对象程序的设计思想。

2 面向对象的3大特征与6大原则

2.1 三大特征

封装

隐藏实现逻辑和细节:使用者只关心使用,复杂的逻辑和大量的细节被隐藏。比如调用各种方法,只管调用,不用管方法怎么实现的,这样子猪都能写代码。

数据和行为的结合:将数据和行为看作一个整体。面向过程编程中,数据和行为是分离的。而在面向对象的编程中,“类”的概念,就是将数据和行为绑定。数据在类中体现为类的属性,即成员变量,行为在类中体现为方法,一个类可以有很多属性和方法。举个例子,比如一个“人”类,可以有很多属性特征,比如多大,多长,多粗(指年龄、头发和手臂),也可以有很多行为方法,比如可以成长,可以剃光头,可以撸铁。这个“人”类的实例就是一个个的人,每个人都有这些属性并且都能进行这些行为,所以每个个体就是这个类的实例对象。我们把“大、长、粗”和“成长、剃光头、撸铁”全部写在一个类里面,并给这个类起名叫“人”,这就叫封装。

继承

代码复用:说白了就是偷懒,写更少的代码,省时省力更省心。比如有一个动物类,又有一个人类,一个狗类。人会拉屎,狗也会拉屎,所有动物都会拉屎。那如果在人类和狗类里都写一遍拉屎代码,岂不是在拉重复的屎?这好吗?这不好。既然所有动物都会拉屎,那我们把拉屎代码写在动物类里,并且让人类和狗类都去继承动物类,是不是相当于人类和狗类都自动会拉屎了?那真是太好了。

多态

一个方法,多种可能的状态:比较常见的实现方式有两种。方式一:继承某个类,重写其中的方法。方式二:实现接口或者抽象方法。举例子:人类和狗类都会拉屎,所以我们把拉屎代码写在动物类里,但是这有问题,因为每个动物拉屎的行为并不一定完全一样,比如狗拉完屎不用擦屁股,人要。所以尽管都是拉屎,我们的代码还是有小差异的,我们可以在人类代码里面重写拉屎函数,给他最后加上一个擦屁股代码,而狗类什么都不改,这样虽然人和狗都是拉屎,但是却有不同的状态,这就是多态。方式二形成的多态也是一样。一个接口或者抽象方法被实现前,只有方法签名,只是个空壳子,这个方法最终长成什么样子,取决于谁来实现它,不同实现它的人可能都导致它最终的行为不一样,这也是一种多态。

2.2 六大原则(SOLID)

Single Responsibility Principle:单一职责原则

一个类就只是一样东西,不同的东西就应该写成两个类。接口也是如此,一个接口尽量只完成一个方面的工作就好,别打肿脸充胖子。

Open Closed Principle:开放闭合原则

对扩展开放,对修改闭合。即,对于一个外人,我允许你用我提供给你的方法去外面乱搞,但是我不允许你把我的里面搞的乱七八糟。也就是说,对于外部调用者,你可以尽情扩展功能,但是不能修改我的内部实现逻辑。

Liskov Substitution Principle:里氏替换原则

干同一件事,如果父类对象能完成,那替换为子类对象也要能完成。其实也很好理解,子类是继承自父类,子类的东西肯定是大于等于父类的,这里就要求子类多出来的那部分东西不会影响父类原有的功能,父类能完成的,子类也一定要能完成。

Law of Demeter:迪米特法则

两个没有关系的模块不要相互调用,如确实要有交流,可以通过接口等第三者来完成。这样可以降低耦合。其实也很好理解,大家都是陌生人的话就别玩群P了啦,怪奇怪的。

Interface Segregation Principle:接口隔离原则

别去实现你不需要的接口或抽象方法,并且类间的依赖关系应该建立在最小的接口上。前半句好理解,后半句其实和前半句是一个意思。大概就是说,AB两个类要通信,有CD两个接口都满足通信要求,但是C接口有10000个方法,D接口有1个方法。如果要用C接口去通信就必须把10000个方法都实现了,傻子才选择C。注意接口隔离原则和单一职责原则的侧重点不一样,单一职责原则强调尽管这个接口有可能定义了很多个方法,但他的功能应该单一,别什么功能都来整一点。而接口隔离原则强调选择最小的接口去实现。这两个原则并不冲突,有可能C接口的10000个方法都是为了某个目的而存在,所以即使它的方法数很多,但它仍满足单一职责原则,它的存在只是为了满足一个需求。而在另一个场景下,只需要像D这样只有一个方法的接口就能满足我们的需求,那按照接口隔离原则,C和D间,明显是选择D去实现。

Dependence Inversion Principle:依赖倒置原则

面向接口编程。直接举例子吧,有两个图形类,圆类和方类,现在A类里有个函数要实现画图功能,要求能画圆或画方,假设画圆的代码有5000行,画方的代码也有5000行,那么如果这两个功能全放在A类,那A类那个函数就有10000行代码,而且这种A类一般是高层模块,除了画图肯定还有一堆功能,那这样A类代码就特别多,这好吗?这不好。而且这只是有两个图形的情况,万一有10个图形呢?A类就爆炸了好吗?那怎么办。答案就是用接口。每个图形类各自实现画图接口,在他们各自类内部的画图方法里去编写自己的画图逻辑。画图的实现交给了各个图形类,那A类是不是只管调用就完事了?其实说白了就是,一些底层模块功能的实现可以写到各自的类里面去,高层模块一般就只需要单纯的调用就完事了。

对于一个接口来说,我们只在interface里面写了一堆方法签名,但是这些方法真正使用的时候,肯定还需要关注两件事,一是方法具体的内容是什么,即方法的实现,也就是大括号里面的内容,二是这个方法啥时候被谁调用。依赖倒置原则告诉我们,因为底层模块的功能相对于高层模块来说较为单一,所以接口的实现应该放在底层模块内部,而调用则交给高层模块去完成,这就叫做面向接口编程。

3 设计模式

可以看看这些,写的挺好的。

1、https://www.jianshu.com/p/9e1f95e5c4e0

2、https://www.jianshu.com/p/94a7a882078d

3、https://www.cnblogs.com/steffen/p/11400509.html

你可能感兴趣的:(面向对象程序设计思想——通俗版)