前言
随着计算机行业的不断发展,人们对于可以给予自身快速成长的技术非常的痴迷。就比如今天要聊的设计模式,学过编程的都知道设计模式,而很少有人会知道它的核心思想是什么,只是一味的照着网络上流行的设计模式 二十三式 依葫芦画瓢。仅做到了知其然而不知其所以然。所以今天来聊聊它出现的意义什么
意义
我们知道一个江湖的组成是非常不容易的,在江湖中也会有很多的门派与帮派,而门派一多就会有各式各样的问题,这时就出来了一个叫做设计模式的东西,来处理门派在发展过程中遇到的一般问题的解决方案。其中的话有以下五经可供参考。
五经
设计模式架构中,有常用来指导设计的 5 大原则,俗称:SOLID
- 单一原则 (SRP)
- 开闭原则 (OCP)
- 里氏替换原则 (LSP)
- 接口隔离原则 (ISP)
- 依赖倒置原则 (DIP)
单一原则
从字面上理解单一的意思可能就代表着你门派业务或者任务的单一等等,比如龙门镖局的创立之初可能就是说押押镖 送送快递之类的。而药仙谷则可能就只是制制药之类的。它们俩之间就不存在什么耦合性关系了。
翻译:一个类只负责完成一个职责或者功能。一个模块应该对一类且仅对一类行为者负责。不要设计大而全的类,要设计粒度小、功能单一的类。单一职责原则是为了实现代码高内聚、低耦合、提高代码的复用性、可读性、可维护性。
判断是否单一:
- 类中的代码行数、函数或者属性过多;
- 类依赖的其他类过多,或者依赖类的其他类过多;
- 私有方法过多;
- 比较难起一个合适的名字;
- 类中大量的方法都是集中操作类中的某几个属性。
误区: 类与模块的划分不是说划分越细越好的,因为拆分的过细,会降低内聚性,增加维护的成本
建议: 在划分类与模块时,尽量从业务出发。而且划分的过程也可以是跟着业务的发展逐步进行的。
// 错误的示范 可以看到客户类当中加入了支付的相关逻辑,明显不单一
class Customer
{
public function getCustomer()
{
echo '客户信息';
}
public function pay()
{
echo '支付金额';
}
}
// 正确示范 将客户的正常信息与支付信息划分开
class Customer
{
public function getCustomer(){
echo '客户信息';
}
}
class CustomerPay
{
public function pay()
{
echo '支付金额';
}
}
开闭原则
随着门派的不断发展,客户量的不断增加,就会有许多扩张方案或者活动之类。就拿龙门镖局为例:周年庆时,门派为了酬谢客户 而举办了一个活动。这个活动由于是新的业务,为了不影响旧的业务的进行,门派就新扩展了一个活动部门专门处理周年庆的事情。
翻译:软件实体(模块、类、方法等)应该对“对扩展开发、对修改关闭”,也可这样理解 那就是添加一个新的功能应该是,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)
注意点:
- 开闭原则并不是完全杜绝修改,而是以最小的代价完成新功能的开发
- 在不同角度来看,修改也可能是扩展。粗粒度下可能是修改,细粒度来看可能是扩展。
里式替换
随着活动办的非常成功,门派业务也是突飞猛进,所以门主及长老打算在荆州再开一个分局,但是分局的相关规章制度是一样的。
翻译:子对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏
违反了里式替换:
- 子类违背父类声明要实现的功能
- 子类违背父类对输入、输出、异常的约定
- 子类违背父类注释中所罗列的任何特殊说明
注意点:
1.父类定义了函数的“约定”(或者协议),那么子类可以改变函数的内部实现逻辑,但不能改变原有的“约定”,比如:输入、输出、异常的约定 甚至包括注释。
接口隔离
在门派创立之初,发布了一个入门申请的规范,只要满足实现了规范上写的就可以龙门镖局了。可是有一天掌门想添加一条关于清退不合格人员,但是如果在入门那个规范里面写就不太好了 所以重新发了一份清退规范。
翻译:客户端不应该强迫依赖它不需要的接口,其中的“客户端”可以理解为接口的调用者或者使用者
接口定义:
- 一组API接口集合
- 单个API接口或函数
- OOP中的接口概念
注意点:
- 接口需要单一,不该让接口的实现类和调用者,依赖不需要的接口函数。
依赖倒置
在第三方招人机构没有发展之前,门派的招人都是自主招人发工资的,而这时候门派与员工必须强耦合了,而这时候第三方人力公司搞出来个劳务派遣,雇主把钱给到人力公司,人力公司去招人 并发工资给员工,通过这样的方式,雇佣双方把对方的直接控制,反转到了让对方来依赖一个标准的派遣模型的接口——人力公司。
翻译:高层模块不要依赖底层模块,高层模块和低层模块应该通过抽象来互相依赖。除此之外,抽象不要依赖具体实现细节,具体实现细节依赖抽象。
ps:在调用链上,调用者属于高层,被调用者属于低层。