1.原则
1.1 开闭原则
开闭原则是指软件实体应当对扩展开放,对修改关闭。“对扩展开放”意味着模块的行为是可以扩展的,“对修改关闭”指对模块行为进行扩展的时候,不必改动模块的源代码或者进行二次代码开发。
可以根据需求随意增加新的类,但是不要修改原有的类。
实现开闭原则的核心之处在于“抽象”。在软件项目中,需求变更比较频繁,这就要求我们需要区分哪些是不变的,哪些是变化的。对于不变的部分,我们可以把这些不变的部分抽象成不变的接口,对于变化的部分,我们可以评估分类,每一个可变的因素都单独封装。
以抽象类为例,对于一些具备相同功能的类进行抽象处理,将公共部分的功能放入抽象类中,所有操作可以调用子类,这样,在对系统进行功能扩展的时候,就可以根据抽象类的子类去实现新的子类。
以接口为例,接口定义子类需要实现子类。扩展的话只需要修改具体的实现类。
1.2 单一职责原则
单一职责原则:就一个类而言,应该仅有一个引起他变化的原因。换而言之,一个类只需要按照职责进行功能设计。
- 防止相同类型的职责,分离到不同的类中。即我们需要提供代码的可重用性
- 同一个类无须编制多余的职责。
实例:需要实现一个产品报表的模块,这个产品报表模块的属性包括出生年月,产品名称,产品类型,品牌,产品价格和产地。具体功能只需要实现查询,出现两种不同的实现方式:
方法一:把所有属性与功能封装在一个接口中,利用实现类去实现接口
方法二:把产品属性封装在一个接口中,产品业务操作功能在另一个接口
1.3 里式代换原则
简单来说,子类必须能够替换掉他们的基类型。
我们在涉及类的继承设计的时候,可以从“父类不能替换子类,而子类可以替换父类”的思路引导下,进行里氏替换原则的实现。
首先,正确的进行继承设计。所有基类的方法都要在其子类中得到实现和重写,并且子类不能写出与业务功能 实现无关的多余方法或实现。
其次,最优的继承层次设计。当其他应用类调用业务功能类的时候,应该先调用其业务功能的基类而不是直接调用业务功能的子类。
关于里式替换原则的使用,策略模式,代理模式可以很好的体现。
简单来说,在我们设计继承的时候,可以用多个子类实现具体的基类,然后使用@Autowired,这样在不同的使用场景下,只需要在容器中注入不同的实现类的bean,就可以使用不同实现类的具体实现方法。
1.4 依赖倒换原则
依赖倒换原则有两个定义:
定义一:高层模块不应该依赖底层模块,二者都应该依赖于抽象,抽象不应该依赖于细节,细节应该依赖于抽象。
定义二:要针对接口编程,不要针对实现编程。
1.5 接口隔离原则
接口隔离原则有两个定义:
定义一:不应该强迫客户依赖于他们不用的方法;
定义二:一个类对另一个类的依赖性应当是建立在最小的接口上;
1.6 迪米特原则
迪米特原则又称最少知识原则,他是指一个对象应当对其他对象有尽可能少的了解,不必与不认识的人知己恩联系。
2.外观模式(门面模式)
提供一个统一的接口去访问多个子系统的多个不同的接口,他为子系统中的一组接口提供了一个统一的高层接口,使用子系统更加容易。
门面模式的大致模型如下:
在这个对象图中,出现了两个角色:
- 门面角色:客户端可以调用这个角色的方法,由这个角色的方法去调用具体模块的方法,
- 子系统角色:可以同时有一个或者多个子系统,每个子系统不是一个单独的类,而是一个类的集合。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
简单示例:
小明想开一个餐馆,要去政府部门办理卫生许可证、办理税务登记和办理工商登记,以前小明要一一亲自去办理,这不是一件容易的事。
政府最近简化了政务办理流程,只用小明访问一次简化政务办理的门面就可以办理到全部证件。
interface Executive{void approve();}class HealthOffice implements Executive{@Overridepublic void approve() {System.out.println("卫生局通过审批");}}class RevenueOffice implements Executive{@Overridepublic void approve() {System.out.println("税务局完成登记");}}class SaicOffice implements Executive{@Overridepublic void approve() {System.out.println("工商局办理营业执照");}}//简化政务办理流程的门面class ApproveFacade {public void wholeApprove() {new HealthOffice().approve();new RevenueOffice().approve();new SaicOffice().approve();}}
测试:
public class FacadeTest {public static void main(String[] args) {ApproveFacade af = new ApproveFacade();//一次调用门面,全部办理af.wholeApprove();}}
门面角色可以理解为一个独立的应用类,他是一种组合子角色系统的方法,然后提供给客户端一个完整的实施流程方法。为子系统提供提供一个集中化和简化的沟通管道。
使用场景:
日志框架中的日志门面就是使用了门面模式。比如说:commons-logging,slf4j,简单来说不是具体的日志解决方案,它只服务于各种各样的日志系统.按照官方的说法,SLF4J是一个用于日志系统的Facade,允许最终用户在部署其应用时使用其所希望的日志System.
数据库连接,一般在我们每一次对数据库进行访问。都要进行以下操作:先得到connect实例,然后打开connct获得连接得到一个statement,执行sql语句进行查询,得到查询结果集。我们可以将这些步骤提取出来,封装在一个类里面。
