巧用设计模式的目的是为了便于代码扩展,减少代码量,现存的设计模式是前人总结经验。主要分为是三种类型:创建型 、结构型、行为型
创建型模式主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创 建代码和使⽤代码。
单例模式⽤来创建全局唯⼀的对象。
⼯⼚模式⽤来创建不同但是相关类型的对象(继承同⼀⽗类或者接⼝的⼀组⼦类),由给定的参数来决定创建哪种类型的对象。
建造者模式是⽤来创建复杂对象,可以通过设置不同的可选参数,“定制化”地创建不同的对象。
原型模式针对创建成本⽐较⼤的对象,利⽤对已有对象进⾏复制的⽅式进⾏创建,以达到节省创建时间的⽬的。
懒汉
public class LazySingleton {private static volatile LazySingleton instance = null;private LazySingleton() {}public synchronized LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}}
饿汉
public class HungrySingleton {private static HungrySingleton instance = new HungrySingleton();private HungrySingleton() {}public static HungrySingleton getInstance() {return instance;}}
静态内部类
public class StaticInnerClassSingleton {private StaticInnerClassSingleton() {}public static StaticInnerClassSingleton getInstance() {return LazyHolder.innerClassSingleton;}private static class LazyHolder {private static StaticInnerClassSingleton innerClassSingleton = new StaticInnerClassSingleton();}}
枚举类
public enum SingletonEmum {INSTANCE;public void doSomething() {System.out.println("value");}}
工厂方法与抽象工厂的区别是:抽象工厂可以在一个工厂内生产多个商品,工厂方法只能生产一个
主要角色:
工厂方法模式
interface Factory{void produce();}class CarFactory implements Factory{@Overridepublic void produce() {System.out.println("汽车工程生产");new Bus();}}class SuperCarFactory implements Factory{@Overridepublic void produce() {System.out.println("超跑汽车工程生产");new SuperCar();}}interface Car{void show();}class Bus implements Car{@Overridepublic void show() {System.out.println("公共汽车。。。");}}class SuperCar implements Car{@Overridepublic void show() {System.out.println("超跑。。。");}}
抽象工厂模式
interface Factory {Product produceEngine();Product produceTyre();}class CarFactory implements Factory {@Overridepublic Product produceEngine() {System.out.println("汽车工厂:生产发动机");return new Engine();}@Overridepublic Product produceTyre() {System.out.println("汽车工厂:生产发轮胎");return new Tyre();}}class SuperCarFactory implements Factory {@Overridepublic Product produceEngine() {System.out.println("超跑汽车工厂:生产发动机");return new Engine();}@Overridepublic Product produceTyre() {System.out.println("超跑汽车工厂:生产发轮胎");return new Tyre();}}interface Product {void show();}class Tyre implements Product {@Overridepublic void show() {System.out.println("轮胎。。。");}}class Engine implements Product {@Overridepublic void show() {System.out.println("发动机。。。");}}
适用场景
参数很多的 bean 初始化,可以对参数的强约束。
实现
使用静态内部类实现:
public class Bean {private String a;private String b;private String c;private String d;private Bean(Builder builder) {a = builder.a;b = builder.b;c = builder.c;d = builder.d;}static class Builder {private String a;private String b;private String c;private String d;public Builder a(String a) {this.a = a;return this;}public Builder b(String b) {this.b = b;return this;}public Builder c(String c) {this.c = c;return this;}public Builder d(String d) {this.d = d;return this;}public Bean build() {return new Bean(this);}}}
使用:
Bean bean = new Bean.Builder().a("a").b("b").c("c").build();
原型模式的克隆分为浅克隆和深克隆,Java 中的 Object 类提供了浅克隆的 clone() 方法,具体原型类只要实现 Cloneable 接口就可实现对象的浅克隆
主要角色:
代码实现
public interface Subject {void request();}public class ConcreteSubject implements Subject {@Overridepublic void request() {System.out.println("执行请求");}}public class Proxy implements Subject {private Subject subject = new ConcreteSubject();public void preRequest() {System.out.println("pre");}@Overridepublic void request() {preRequest();subject.request();afterRequest();}public void afterRequest() {System.out.println("after");}public static void main(String[] args) {Proxy proxy =new Proxy();proxy.request();}}
定义
桥接(Bridge)模式:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
抽象化和实现化之间使用关联关系(组合或者聚合关系)而不是继承关系,从而使两者可以相对独立地变化,这就是桥接模式的用意。
适用场景:
实现
主要角色
abstract class Bag {Color color;public void setColor(Color color) {this.color = color;}abstract void echoName();}class HandBag extends Bag {@Overridevoid echoName() {System.out.println(color.getColor() + "的挎包");}}class Wallet extends Bag {@Overridevoid echoName() {System.out.println(color.getColor() + "的钱包");}}interface Color {String getColor();}class Yellow implements Color{@Overridepublic String getColor() {return "黄";}}class Red implements Color{@Overridepublic String getColor() {return "红";}}
定义
装饰(Decorator)模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式
jdk io 就使用了装饰器模式,例如,InputStream 的子类 FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有 Writer 的子类 BufferedWriter、FilterWriter 以及 PrintWriter 等,它们都是抽象装饰类。
BufferedReader in=new BufferedReader(new FileReader("filename.txtn));String s=in.readLine();
应用场景
当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰模式却很好实现。
实现
主要角色
public interface Component {void operation();}public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("Concrete Component operation");}}public class Decorator implements Component{Component component;public Decorator(Component component){this.component = component;}@Overridepublic void operation() {component.operation();}}public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}public void addFunction(){System.out.println("add a function");}@Overridepublic void operation() {addFunction();super.operation();}}public class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}public void addFunction(){System.out.println("add b function");}@Overridepublic void operation() {addFunction();super.operation();}}public static void main(String[] args) {Component component = new ConcreteComponent();Decorator decorator = new ConcreteDecoratorA(component);decorator.operation();}
这样做的好处是可以通过组合形成更多的构件功能,例如如上代码,可以组装出具有 a 功能的 ConcreteComponent,具有 b 功能的 ConcreteComponent,或者新增一个 NewConcreteComponent。进而可以组装出具有 a 功能的 NewConcreteComponent
定义
适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
实现
主要角色
类适配器模式
对象适配器模式
定义
外观(Facade)模式的定义:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
实现
主要角色
定义
组合(Composite)模式的定义:有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性
实现
主要角色
定义
享元(Flyweight)模式的定义:运用共享技术来有効地支持大量细粒度对象的复用。它通过共享已经存在的又橡来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
实现
主要角色
定义
模板方法(Template Method)模式:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
父类中定义公共方法或者执行步骤,有差异的部分由具体的子类去实现。
适用场景:
实现
主要角色
为了避免子类较多,可以考虑匿名内部类,JedisCluster 的命令实现就是一个很好的例子。
开源 demo 案例
JedisClusterCommand
的实现即是一个明显的例子。JedisClusterCommand
实现了分槽,获取 connect,执行命令,重试等公共操作。子类中实现具体的执行命令。
定义
策略模式定义了一系列的算法,并将每一个算法封装起来,使他们可以相互替换
适合场景
当你写代码的时候发现一个操作有好多种实现方法,而你需要根据不同的情况使用 if-else 等分支结构来确定使用哪种实现方式的时候,想一想这个模式。
实现
主要角色:
定义
命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
适合场景:
实现
主要角色:
开源 demo 案例
Tomcat 中命令模式在 Connector 和 Container 组件之间有体现,Tomcat 作为一个应用服务器,无疑会接受到很多请求,如何分配和执行这些请求是必须的功能。
Connector 和 Container 两个接口。Connector 是抽象命令请求者,Container 是抽象命令接收者,server 是这一切的缘由,HttpProcessor 是抽象命令。
在 tomcat 中的实现形式是:server 需要 Connector 来接受来自外接的 Http 请求,然后 Connector 接受到请求,并创建了命令 HttpProcessor,然后 server 将这个命令交给了 Container 接收者。
定义
观察者(Observer)模式: 指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式。
实现
主要角色
定义
它通过将请求的发送者和接收者解耦,使多个对象都有机会处理请求。在这个模式中,请求沿着一个处理链依次传递,直到有一个对象能够处理它为止。
实现
主要角色
开源 demo 案例