背景
工作伊始,由于对互联网业务、职场生活不算熟悉,在入职的前两年里,专注发力理解业务。由于处于初创->爆发期的业务团队,主要构建了面向业务开发的思维模式,掌握了一些业务工作的诀窍。但作为一个coder,设计模式与算法是深厚的内功,无论什么情况都不应忽视。因此会有意识的分配一部分时间来夯实这部分知识。同时在后续的工作过程中,力求有意识的使用php的面向对象特性,构建扩展性好、可阅读性更强的代码。而设计模式基于面向对象思想,因此,学习设计模式首先就要理解面向对象的设计原则。
参考资料
正文
非官方资料(面经上)总结面向对象(实际上是从C++为BASE出发理解)的三大特性是:封装、继承(代码重用)、多态(接口重用):
-
封装
定义:对象和类的主要特性,把客观的事物抽象,隐藏事物属性和实现细节,仅对外公开接口,控制程序中属性的读写访问级别。
目的:为了安全、简化编程,使用者不需要了解细节,通过外部接口以特定的访问权限使用类的成员。
基本要求:所有属性私有化,对每个属性设置getter、setter方法;如果有一个带参数的构造函数,一定要辅以一个不带参数的构造函数。对每个类进行测试。
落地PHP:所有属性私有化,对每个属性设置getter、setter,或者实现标准的__get _set magic method,构造函数的参数应当带有默认值,以保证参数列表为空的调用合法 -
继承
定义: 我们通常把两个类具有相同的特征(属性)和行为(方法)时,抽取相同部分形成一个父类。实际使用场景中需要对具体事物进行分析,进行有效父类抽象,以便获得更好的重用效果。私有属性、方法、构造方法都不能被继承。当有需要被继承的相关属性、方法时,就要用protected关键字。被继承的类称为“基类”、“父类”或“超类”,继承创建的新类叫做“子类”,派生类“。
目的: 实现代码的复用,继承现有类并扩展子类功能。
基本要求:实现方法有“继承(Inheritance)”和“组合(Composition)”。在某些语言中一个类可以继承多个基类,这个和语言特性相关。实现方式有三种:实现继承、接口继承、可视继承。继承非常需要注意的是,父子类之间应当是实现/泛化关系,即is-a的关系,动物和猫是继承关系,猫和脚则不是。
落地PHP: php中只允许继承一个基类,实现多重继承,可以通过多级继承来实现(但实际上不推荐继承超过3层)。同时为了弥补这种局限,php提供了interface类型和php5.3后增加的trait类型,interface允许被implement或extends,trait通过use关键字来引用,大多数用在组合的场景下。 -
多态
定义: 允许将父对象设置为和一个或者更多TA的子对象相等的技术,复制之后,父对象可以根据当前赋值给他的子对象的特性以不同的方式运行。简而言之,允许将子类类型的指针赋值给父类类型的指针。这个是面向对象的精髓特征。
目的: 封装可以隐藏细节,使代码模块化;继承可以扩展已有代码模块(类);目的都是为了实现代码重用,多态则为了实现接口重用。增强程序的可扩展性及可维护性。
基本要求: 实现方法有“覆盖”和“重载”。覆盖是子类重新定义父类虚函数的做法。重载是指允许存在多个同名函数,根据参数表不同,单独编程。实际上重载概念并不属于OO,取决于编译器是否可以根据参数表区分同名函数,因此重载与多态无关,对于同步不同参数表的函数调用逻辑,在编译期间就已经确定了,是静态的。真正与多态相关的是“覆盖”。当子类重新定义了父类的虚函数之后,父类指针根据赋给TA的不同的子类指针,“动态”的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的。因此,这样的函数地址是在程序运行期间绑定的(晚绑定)。结论就是:重载是一种语言特性,与多态、OO无关。
最终确定一个概念:重载:编译期确定 多态:运行期才确定(晚绑定)
特性tree如图(来源网路,如有不便,请联系侵删)
-
OO开发范式大致为:
划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。 -
类之间的关系:
留待UML学习部分详细叙述。
下表简单列出了OOP的核心设计原则
设计原则 | 定义 | 使用频率 |
---|---|---|
单一职责(SRP) | 一个类负责一个功能领域的相应职责 | ssss |
开闭原则(OCP) | 软件实体应对扩展开放而对修改关闭 | sssss |
里氏代换原则(LSP) | 所有引用积累对象的地方可以透明地使用其子类对象 | sssss |
依赖倒转原则(DIP) | 抽象不依赖于细节,细节应该依赖于抽象 | sssss |
接口隔离原则(ISP) | 使用多个专门的接口,而不使用单一的总接口 | ss |
合成复用原则(CRP) | 尽量使用对象组合,而不是继承来达到复用目的 | ssss |
迪米特法则(LoD) | 一个软件实体应当尽可能少地与其他实体发生相互作用 | sss |
前五个常被称为5大原则