设计模式:
单例(Singleton)模式
定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。
第 1 种:懒汉式单例
类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例
1 public class LazySingleton { 2 private static volatile LazySingleton instance = null; //保证 instance 在所有线程中同步 3 private LazySingleton() { 4 } //private 避免类在外部被实例化 5 public static synchronized LazySingleton getInstance() { 6 //getInstance 方法前加同步 7 if (instance == null) { 8 instance = new LazySingleton(); 9 } 10 return instance; 11 } 12 }
第 2 种:饿汉式单例
类一旦加载就创建一个单例
1 public class HungrySingleton { 2 private static final HungrySingleton instance = new HungrySingleton(); 3 private HungrySingleton() { 4 } 5 public static HungrySingleton getInstance() { 6 return instance; 7 } 8 }
装饰器(Decorator)模式
定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。装饰器模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。
- ConcreteComponent(具体对象)和Decorator(抽象装饰器)实现相同的Conponent(接口)并且Decorator(抽象装饰器)里面持有Conponent(接口)对象,可以传递请求。
- ConcreteComponent(具体装饰器)覆盖Decorator(抽象装饰器)的方法并用super进行调用,传递请求。
1 public class DecoratorPattern { 2 public static void main(String[] args) { 3 Component p = new ConcreteComponent(); 4 p.operation(); 5 System.out.println("---------------------------------"); 6 Component d = new ConcreteDecorator(p); 7 d.operation(); 8 } 9 } 10 //抽象构件角色 11 interface Component { 12 public void operation(); 13 } 14 //具体构件角色 15 class ConcreteComponent implements Component { 16 public ConcreteComponent() { 17 System.out.println("创建具体构件角色"); 18 } 19 public void operation() { 20 System.out.println("调用具体构件角色的方法operation()"); 21 } 22 } 23 //抽象装饰角色 24 class Decorator implements Component { 25 private Component component; 26 public Decorator(Component component) { 27 this.component = component; 28 } 29 public void operation() { 30 component.operation(); 31 } 32 } 33 //具体装饰角色 34 class ConcreteDecorator extends Decorator { 35 public ConcreteDecorator(Component component) { 36 super(component); 37 } 38 public void operation() { 39 super.operation(); 40 addedFunction(); 41 } 42 public void addedFunction() { 43 System.out.println("为具体构件角色增加额外的功能addedFunction()"); 44 } 45 }
适配器模式(Adapter)
定义:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
类适配器:Adapter类(适配器)继承Adaptee类(源角色)实现Target接口(目标角色)
对象适配器:Adapter类(适配器)持有Adaptee类(源角色)对象实例,实现Target接口(目标角色
)
- 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
- 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
- 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
1 //客户端代码 2 public class ClassAdapterTest 3 { 4 public static void main(String[] args) 5 { 6 System.out.println("类适配器模式测试:"); 7 Target target = new ClassAdapter(); 8 target.request(); 9 } 10 } 11 //目标接口 12 interface Target 13 { 14 public void request(); 15 } 16 //适配者接口 17 class Adaptee 18 { 19 public void specificRequest() 20 { 21 System.out.println("适配者中的业务代码被调用!"); 22 } 23 } 24 //类适配器类 25 class ClassAdapter extends Adaptee implements Target 26 { 27 public void request() 28 { 29 specificRequest(); 30 } 31 }
1 //客户端代码 2 public class ObjectAdapterTest 3 { 4 public static void main(String[] args) 5 { 6 System.out.println("对象适配器模式测试:"); 7 Adaptee adaptee = new Adaptee(); 8 Target target = new ObjectAdapter(adaptee); 9 target.request(); 10 } 11 } 12 13 //目标接口 14 interface Target 15 { 16 public void request(); 17 } 18 //适配者接口 19 class Adaptee 20 { 21 public void specificRequest() 22 { 23 System.out.println("适配者中的业务代码被调用!"); 24 } 25 } 26 27 //对象适配器类 28 class ObjectAdapter implements Target 29 { 30 private Adaptee adaptee; 31 public ObjectAdapter(Adaptee adaptee) 32 { 33 this.adaptee=adaptee; 34 } 35 public void request() 36 { 37 adaptee.specificRequest(); 38 } 39 }
模板方法(Template Method)模式
定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
1. 抽象类/抽象模板(Abstract Class)负责给出一个算法的轮廓和骨架
模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
基本方法:是整个算法中的一个步骤,包含以下几种类型。
- 抽象方法:在抽象类中声明,由具体子类实现。
- 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
- 钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种
2. 具体子类/具体实现(Concrete Class)实现抽象类中所定义的抽象方法和钩子方法
1 public class TemplateMethodPattern { 2 public static void main(String[] args) { 3 AbstractClass tm = new ConcreteClass(); 4 tm.TemplateMethod(); 5 } 6 } 7 //抽象类 8 abstract class AbstractClass { 9 //模板方法 10 public void TemplateMethod() { 11 SpecificMethod(); 12 abstractMethod1(); 13 abstractMethod2(); 14 } 15 //具体方法 16 public void SpecificMethod() { 17 System.out.println("抽象类中的具体方法被调用..."); 18 } 19 //抽象方法1 20 public abstract void abstractMethod1(); 21 //抽象方法2 22 public abstract void abstractMethod2(); 23 } 24 //具体子类 25 class ConcreteClass extends AbstractClass { 26 public void abstractMethod1() { 27 System.out.println("抽象方法1的实现被调用..."); 28 } 29 public void abstractMethod2() { 30 System.out.println("抽象方法2的实现被调用..."); 31 } 32 }
工厂(Factory)模式
定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。
- 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
- 抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
- 具体产品(ConcreteProduct):是简单工厂模式的创建目标。
1 public class Client { 2 public static void main(String[] args) { 3 } 4 //抽象产品 5 public interface Product { 6 void show(); 7 } 8 //具体产品:ProductA 9 static class ConcreteProduct1 implements Product { 10 public void show() { 11 System.out.println("具体产品1显示..."); 12 } 13 } 14 //具体产品:ProductB 15 static class ConcreteProduct2 implements Product { 16 public void show() { 17 System.out.println("具体产品2显示..."); 18 } 19 } 20 final class Const { 21 static final int PRODUCT_A = 0; 22 static final int PRODUCT_B = 1; 23 static final int PRODUCT_C = 2; 24 } 25 static class SimpleFactory { 26 public static Product makeProduct(int kind) { 27 switch (kind) { 28 case Const.PRODUCT_A: 29 return new ConcreteProduct1(); 30 case Const.PRODUCT_B: 31 return new ConcreteProduct2(); 32 } 33 return null; 34 } 35 } 36 }
工厂方法(FactoryMethod)模式
定义:是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
1 public class AbstractFactoryTest { 2 public static void main(String[] args) { 3 try { 4 Product a; 5 AbstractFactory af; 6 af = (AbstractFactory) ReadXML1.getObject(); 7 a = af.newProduct(); 8 a.show(); 9 } catch (Exception e) { 10 System.out.println(e.getMessage()); 11 } 12 } 13 } 14 //抽象产品:提供了产品的接口 15 interface Product { 16 public void show(); 17 } 18 //具体产品1:实现抽象产品中的抽象方法 19 class ConcreteProduct1 implements Product { 20 public void show() { 21 System.out.println("具体产品1显示..."); 22 } 23 } 24 //具体产品2:实现抽象产品中的抽象方法 25 class ConcreteProduct2 implements Product { 26 public void show() { 27 System.out.println("具体产品2显示..."); 28 } 29 } 30 //抽象工厂:提供了厂品的生成方法 31 interface AbstractFactory { 32 public Product newProduct(); 33 } 34 //具体工厂1:实现了厂品的生成方法 35 class ConcreteFactory1 implements AbstractFactory { 36 public Product newProduct() { 37 System.out.println("具体工厂1生成-->具体产品1..."); 38 return new ConcreteProduct1(); 39 } 40 } 41 //具体工厂2:实现了厂品的生成方法 42 class ConcreteFactory2 implements AbstractFactory { 43 public Product newProduct() { 44 System.out.println("具体工厂2生成-->具体产品2..."); 45 return new ConcreteProduct2(); 46 } 47 }
1 interface AbstractFactory { 2 public Product1 newProduct1(); 3 public Product2 newProduct2(); 4 } 5 class ConcreteFactory1 implements AbstractFactory { 6 public Product1 newProduct1() { 7 System.out.println("具体工厂 1 生成-->具体产品 11..."); 8 return new ConcreteProduct1(); 9 } 10 public Product2 newProduct2() { 11 System.out.println("具体工厂 1 生成-->具体产品 21..."); 12 return new ConcreteProduct2(); 13 } 14 } 15 //抽象产品:提供了产品的接口 16 interface Product { 17 public void show(); 18 } 19 //具体产品1:实现抽象产品中的抽象方法 20 class ConcreteProduct1 implements Product { 21 public void show() { 22 System.out.println("具体产品1显示..."); 23 } 24 } 25 //具体产品2:实现抽象产品中的抽象方法 26 class ConcreteProduct2 implements Product { 27 public void show() { 28 System.out.println("具体产品2显示..."); 29 } 30 }
观察者(Observer)模式
定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
- 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
1 import java.util.*; 2 public class ObserverPattern { 3 public static void main(String[] args) { 4 Subject subject = new ConcreteSubject(); 5 Observer obs1 = new ConcreteObserver1(); 6 Observer obs2 = new ConcreteObserver2(); 7 subject.add(obs1); 8 subject.add(obs2); 9 subject.notifyObserver(); 10 } 11 } 12 //抽象目标 13 abstract class Subject { 14 protected List<Observer> observers = new ArrayList<Observer>(); 15 //增加观察者方法 16 public void add(Observer observer) { 17 observers.add(observer); 18 } 19 //删除观察者方法 20 public void remove(Observer observer) { 21 observers.remove(observer); 22 } 23 public abstract void notifyObserver(); //通知观察者方法 24 } 25 //具体目标 26 class ConcreteSubject extends Subject { 27 public void notifyObserver() { 28 System.out.println("具体目标发生改变..."); 29 System.out.println("--------------"); 30 for (Object obs : observers) { 31 ((Observer) obs).response(); 32 } 33 } 34 } 35 //抽象观察者 36 interface Observer { 37 void response(); //反应 38 } 39 //具体观察者1 40 class ConcreteObserver1 implements Observer { 41 public void response() { 42 System.out.println("具体观察者1作出反应!"); 43 } 44 } 45 //具体观察者1 46 class ConcreteObserver2 implements Observer { 47 public void response() { 48 System.out.println("具体观察者2作出反应!"); 49 } 50 }
代理(Proxy)模式
定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
- 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
- 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
- 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
1 public class ProxyTest { 2 public static void main(String[] args) { 3 Proxy proxy = new Proxy(); 4 proxy.Request(); 5 } 6 } 7 //抽象主题 8 interface Subject { 9 void Request(); 10 } 11 //真实主题 12 class RealSubject implements Subject { 13 public void Request() { 14 System.out.println("访问真实主题方法..."); 15 } 16 } 17 //代理 18 class Proxy implements Subject { 19 private RealSubject realSubject; 20 public void Request() { 21 if (realSubject == null) { 22 realSubject = new RealSubject(); 23 } 24 preRequest(); 25 realSubject.Request(); 26 postRequest(); 27 } 28 public void preRequest() { 29 System.out.println("访问真实主题之前的预处理。"); 30 } 31 public void postRequest() { 32 System.out.println("访问真实主题之后的后续处理。"); 33 } 34 }
建造者(Builder)模式
定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成
- 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
- 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
- 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
1 public class Client { 2 public static void main(String[] args) { 3 Builder builder = new ConcreteBuilder(); 4 Director director = new Director(builder); 5 Product product = director.construct(); 6 product.show(); 7 } 8 } 9 // 产品角色 10 class Product { 11 private String partA; 12 private String partB; 13 private String partC; 14 public void setPartA(String partA) { 15 this.partA = partA; 16 } 17 public void setPartB(String partB) { 18 this.partB = partB; 19 } 20 public void setPartC(String partC) { 21 this.partC = partC; 22 } 23 public void show() { 24 //显示产品的特性 25 } 26 } 27 // 抽象建造者 28 abstract class Builder { 29 //创建产品对象 30 protected Product product = new Product(); 31 public abstract void buildPartA(); 32 public abstract void buildPartB(); 33 public abstract void buildPartC(); 34 //返回产品对象 35 public Product getResult() { 36 return product; 37 } 38 } 39 // 具体建造者 40 public class ConcreteBuilder extends Builder { 41 public void buildPartA() { 42 product.setPartA("建造 PartA"); 43 } 44 public void buildPartB() { 45 product.setPartB("建造 PartB"); 46 } 47 public void buildPartC() { 48 product.setPartC("建造 PartC"); 49 } 50 } 51 // 指挥者 52 class Director { 53 private Builder builder; 54 public Director(Builder builder) { 55 this.builder = builder; 56 } 57 //产品构建与组装方法 58 public Product construct() { 59 builder.buildPartA(); 60 builder.buildPartB(); 61 builder.buildPartC(); 62 return builder.getResult(); 63 } 64 }