- 设计模式分类
总体来说设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。
- 设计模式原则
六个原则
- 开闭原则:对扩展开发对修改关闭,多使用接口和继承
- 里氏代换原则:对开闭的补充,子类继承基类,实现抽象化
- 依赖倒转原则:开闭的基础,直接对接口编程
- 接口隔离原则:使用多个隔离接口,降低耦合度
- 最少知道原则:一个实体降低与其他实体发生相互作用
- 合成复用原则:使用合成、聚合的方式,不使用继承
- 具体模式分析
- 创建型
- 工厂模式
- 普通工厂
- 工厂模式
- 创建型
接口A
实现1
实现2
工厂方法(根据字符串返回具体实现)
- 多个工厂方法
多个工厂方法,不需要传递参数,直接new即可
- 静态工厂方法
将工厂方法设置成静态,直接调用
- 抽象工厂
接口A
实现1
实现2
工厂方法1
工厂方法2
工厂接口(直接实例化工厂接口的工厂类实现即可),体现闭包原则
- 单例模式
懒汉模式
- 双重校验锁
public class Singleton{
private volatile static Singleton singleton = null; //注意此处加上了volatile关键字
private Singleton(){
System.out.println("构造函数被调用");
}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
//return singleton; //有人提议在此处进行一次返回
}
//return singleton; //也有人提议在此处进行一次返回
}
}
return singleton;
}
}
- 静态内部类
Singleton类被加载不会创建单例对象,除非调用里面的getInstance()方法
public class Singleton {
private Singleton(){
System.out.println("构造函数被调用");
}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
private static class SingletonHolder{
private static Singleton instance = new Singleton();
}
}
饿汉模式
在Singleton类被加载时创建了一个实例对象
public class Singleton{
private static Singleton singleton = new Singleton(); //在定义变量时就将其实例化
private Singleton(){
System.out.println("构造函数被调用");
}
public static Singleton getInstance(){
return singleton;
}
}
- 建造者模式
描述:将抽象工厂中的实现在一个类中集成一个符合的对象
- 原型模式
描述:将一个对象作为原型,对其进行复制、克隆,产生一个类似对象
Cloneable
- 浅复制:基本类型重新创建,引用类型还指向原来的引用
- 深复制:基本类型重新创建,引用类型也重新创建
- 结构性
- 适配器模式
描述:将一个接口转换成客户端期望的接口,解决不兼容问题
分类:类的适配器、对象适配器、接口适配器
- 类适配器
Source类方法1
Targetable接口方法1 +方法2
适配器类继承Source实现Targetable接口
调用类newSource实例,实例化适配器类,执行方法
- 对象适配器
与类适配器模式相同,将Adapter类作修改,这次不继承Source类,而是持有(构造函数)Source类的实例
调用类实例化Sourceable接口的Proxy实现,调用方法1
- 接口适配器
接口中的所有方法不必都实现时使用抽象类的机制实现
Sourceable接口
Wrapper抽象类实现Sourceable接口
适配器类继承Wrapper抽象类,实现需要的方法即可
调用类实例化适配器类即可
- 装饰模式
描述:动态的给一个对象添加新的功能
Sourceable接口方法1
Source被修饰类,实现Sourceable接口
Decorator修饰类,实现Sourceable接口,持有(构造函数)Source被修饰类实例
调用类newSource实例,实例化Decorator修饰类,调用方法1
- 代理模式
描述:增加一个代理类,对原有方法做一些before、after操作
Sourceable接口方法1
Source类实现Sourceable接口
Proxy代理类实现Sourceable接口,持有(构造函数里new)Source类实例,新增before、after等方法
调用类实例化Sourceable接口的Proxy实现,调用方法1
- 外观模式
描述:将类与类之间的关系放在Facade类中,降低类之间的耦合性
CPU类,start、stop
Disk类,start、stop
PC类:实例化CPU、Disk,start、stop中调用CPU与Disk的start、stop
调用类调用PC类的start、stop
- 桥接模式
描述:将抽象化与实现化分离,解耦,如JDBC
Sourceable接口方法1
SourceSub1类实现Sourceable接口
SourceSub2类实现Sourceable接口
Bridge抽象类,持有(get、set)Sourceable类,方法1 Sourceable.method
MyBridge类继承Bridge抽象类,方法1getSource().method()
调用类中
Bridge bridge = new MyBridge();
/*调用第一个对象*/
Sourceable source1 = new SourceSub1();
bridge.setSource(source1);
bridge.method();
/*调用第二个对象*/
Sourceable source2 = new SourceSub2();
bridge.setSource(source2);
bridge.method();
- 组合模式
描述:又叫部分-整体模式,多用于处理树形结构
public class TreeNode {
private String name;
private TreeNode parent;
private Vector<TreeNode> children = new Vector<TreeNode>();
//get、set
//添加孩子节点
public void add(TreeNode node){
children.add(node);
}
//删除孩子节点
public void remove(TreeNode node){
children.remove(node);
}
//取得孩子节点
public Enumeration<TreeNode> getChildren(){
return children.elements();
}
}
publicclass Tree {
TreeNoderoot = null;
publicTree(String name) {
root= new TreeNode(name);
}
publicstatic void main(String[] args) {
Treetree = new Tree("A");
TreeNodenodeB = new TreeNode("B");
TreeNodenodeC = new TreeNode("C");
nodeB.add(nodeC);
tree.root.add(nodeB);
System.out.println("buildthe tree finished!");
}
}
- 享元模式
描述:实现对象的共享,通常与工厂合用,工厂需要检查当前共享池里是否有对象,无就创建新的。如JDBC连接池,建一个工厂,将url、dbname等作为内部数据,其他作为外部数据,方法调用时,作为参数传进去
publicclass ConnectionPool {
privateVector<Connection> pool;
/*公有属性*/
privateString url = "jdbc:mysql://localhost:3306/test";
privateString username = "root";
privateString password = "root";
privateString driverClassName = "com.mysql.jdbc.Driver";
privateint poolSize = 100;
privatestatic ConnectionPool instance = null;
Connectionconn = null;
/*构造方法,做一些初始化工作*/
privateConnectionPool() {
pool= new Vector<Connection>(poolSize);
for(int i = 0; i < poolSize; i++) {
try{
Class.forName(driverClassName);
conn= DriverManager.getConnection(url, username, password);
pool.add(conn);
}catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (SQLException e) {
e.printStackTrace();
}
}
}
/*返回连接到连接池 */
publicsynchronized void release() {
pool.add(conn);
}
/*返回连接池中的一个数据库连接*/
publicsynchronized Connection getConnection() {
if(pool.size() > 0) {
Connectionconn = pool.get(0);
pool.remove(conn);
returnconn;
}else {
returnnull;
}
}
}
- 行为型
- 策略模式
描述:(父子类)提供一个接口,一系列实现类,使各个实现类算法可以相互替换
- 模板方法模式
描述:(父子类)一个抽象类,定义一个主方法,定义n个方法(抽象和实际);定义一个类,继承该抽象类,重写抽象方法;通过调用抽象类,实现对子类的调用
- 观察者模式
描述:(类与类)当一个对象变化时,会通知其他依赖该对象的对象
- 迭代器模式
描述:(类与类)如集合中的迭代器,包括被遍历对象和迭代器对象
- 责任链模式
描述:(类与类)多个对象,每个对象持有对下一个对象的引用,请求在这条链上传递,直到请求被处理,但是客户端并不知道谁处理的
Handler接口,operator方法
AbstractHandler抽象类,持有(get、set)Handler接口
MyHandler集成AbstractHandler实现Handler,operator方法中getHandler().operator();
调用类
MyHandler h1 = new MyHandler("h1");
MyHandler h2 = new MyHandler("h2");
MyHandler h3 = new MyHandler("h3");
h1.setHandler(h2);
h2.setHandler(h3);
h1.operator();
- 命令模式
描述:(类与类)司令员下达命令,命令传递到士兵,士兵执行;三者解耦;如Struts
Command接口,exe方法
Receiver类,action方法
MyCommand类实现Command接口,持有(构造函数)Receiver类实例,exe方法中receiver.action()
Invoker类,持有(构造函数)Command接口实例,action方法中command.exe()
调用类
Receiverreceiver = new Receiver();
Commandcmd = new MyCommand(receiver);
Invokerinvoker = new Invoker(cmd);
invoker.action();
- 备忘录模式
描述:(类的状态),保存对象的一个状态,用于恢复对象,备份模式
Original类是原始类,里面有需要保存的属性value及创建一个备忘录类,用来保存value值
Memento类是备忘录类
Storage类是存储备忘录的类,持有Memento类的实例
- 状态模式
描述:(类的状态)当对象的状态改变时则改变其行为
State类是个状态类
Context类可以实现切换
调用类,set不同状态,context类调用State中不同方法
- 访问者模式
描述:(通过中间类)把数据结构与作用于结构上的操作解耦,适用于数据结构稳定当时算法易变的系统
- 中介者模式
描述:(通过中间类)降低类类之间的耦合,具体类类之间的关系和调度交给中介者,如Spring容器
User抽象类,持有(构造函数、get)Mediator接口
User1、User2继承User
Mediator接口
MyMediator类实现Mediator接口,持有(get)User1、User2
调用类
Mediatormediator = new MyMediator();
mediator.createMediator();
mediator.workAll();
- 解释器模式
描述:(通过中间类),应用在OOP开发中的编译器的开发中