一、设计模式简述
概念:
设计模式(Design Pattern)简单的讲就是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。
1995 年,GoF(Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称「GoF设计模式」。
意义:
设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。软件设计模式只是一个引导。在具体的软件幵发中,必须根据设计的应用系统的特点和要求来恰当选择。对于简单的程序开发,可能写一个简单的算法要比引入某种设计模式更加容易。但对大项目的开发或者框架设计,用设计模式来组织代码显然更好。
二、设计原则
开闭原则:
当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。
里氏替换原则:
子类可以扩展父类的功能,但不能改变父类原有的功能。
依赖倒置原则:
实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。
单一职责原则:
核心就是控制类的粒度大小、将对象解耦、提高其内聚性。
接口隔离原则:
要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法。
迪米特法原则:
如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。
合成复用原则:
尽量首先使用合成/聚合的方式,而不是使用继承。
总结:高内聚,低耦合。
从模块粒度来看,高内聚:尽可能类的每个成员方法只完成一件事(最大限度的聚合); 低耦合:减少类内部,一个成员方法调用另一个成员方法。从类角度来看, 高内聚低耦合:减少类内部,对其他类的调用;从功能块来看 高内聚低耦合:减少模块之间的交互复杂度(接口数量,参数数据)即横向:类与类之间、模块与模块之间;纵向:层次之间;尽可能,内容内聚,数据耦合。
三、结构图
四、代理设计模式
应用场景
在有些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代理对象。例如,购买火车票不一定要去火车站买,可以通过 12306 网站或者去火车票代售点买。又如找女朋友、找保姆、找工作等都可以通过找中介完成。
代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
代理模式的主要优点有:
代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
代理对象可以扩展目标对象的功能;
代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;
其主要缺点是:
在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
增加了系统的复杂度;
代理模式的结构与实现
代理模式的结构比较简单,主要是通过定义一个继承抽象角色的代理来包含真实角色,从而实现对真实角色的访问,下面来分析其基本结构和实现方法。
1. 模式的结构
代理模式的主要角色如下。
抽象角色(Abstract)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
真实角色(Real=)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
代理角色(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
2. 模式的实现
代理模式的实现代码如下:
public class TestProxy {
public static void main(String[] args){
/*Proxy proxy = new Proxy();
Pig pig = new Pig();
proxy.setPig(pig);
proxy.happyMarry();*/
new Proxy (new Pig()).happyMarry();
new Thread(new Runnable(){}).start();
}
}
// 抽象角色
interface Marry {
void happyMarry();
}
// 真实角色
class Pig implements Marry {
public void happyMarry() {
System.out.println("猪八戒和嫦娥一起奔月了.....");
}
}
// 代理角色
class Proxy implements Marry {
private Pig pig;
/*public void setPig(Pig pig) {
this.pig=pig;
}*/
public Proxy (Pig pig) {
this.pig=pig;
}
@Override
public void happyMarry() {
ready();
pig.happyMarry();
after();
}
private void after() {
System.out.println("布置婚礼现场。。。。");
}
private void ready() {
System.out.println("闹洞房。。。。");
}
}