参考:
https://www.cnblogs.com/pony1223/p/7608955.html
http://c.biancheng.net/view/1390.html
单例模式
特点
某个类只能有一个实例,提供一个全局的访问点。
应用场景
- Windows的Task Manager(任务管理器)
- 数据库连接池的设计
- 在Spring中,每个Bean默认就是单例的
- 读取配置文件的类,一般也只有一个对象
饿汉式
public class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
懒汉式
public class LazySingleton {
private static volatile LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (null == instance) {
synchronized (LazySingleton.class){
if (null == instance) { //双重检查
instance = new LazySingleton();
}
}
}
return instance;
}
}
静态内部类
public class StaticSingleton {
private StaticSingleton() {
}
private static class SingletonClassInstance {
private static final StaticSingleton instance = new StaticSingleton();
}
public static StaticSingleton getInstance() {
return SingletonClassInstance.instance;
}
}
工厂模式
应用场景
- JDBC中Connection对象的获取
- Hibernate中SessionFactory创建Session
- Spring中IOC容器创建bean对象
简单工厂
一个工厂类根据传入的参量决定创建出那一种产品类的实例。
public class SimpleFactoryTest {
public static void main(String[] args) {
Product product1 = SimpleFactory.makeProduct(1);
product1.show();
Product product2 = SimpleFactory.makeProduct(2);
product2.show();
}
}
//抽象产品
interface Product {
void show();
}
//产品1
class Product1 implements Product {
@Override
public void show() {
System.out.println("具体产品1显示...");
}
}
//产品2
class Product2 implements Product {
@Override
public void show() {
System.out.println("具体产品2显示...");
}
}
//工厂
class SimpleFactory {
public static Product makeProduct(int kind) {
if (kind == 1) {
return new Product1();
} else if (kind == 2) {
return new Product2();
}
return null;
}
}
工厂方法
定义一个创建对象的接口,让子类决定实例化那个类。
public class AbstractFactoryTest {
public static void main(String[] args) {
try {
Product a;
AbstractFactory af;
af = (AbstractFactory) Class.forName("com.cc.pattern.ConcreteFactory1").newInstance();
a = af.newProduct();
a.show();
System.out.println("***********");
af = (AbstractFactory) Class.forName("com.cc.pattern.ConcreteFactory2").newInstance();
a = af.newProduct();
a.show();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
//抽象产品:提供了产品的接口
interface Product {
public void show();
}
//具体产品1:实现抽象产品中的抽象方法
class ConcreteProduct1 implements Product {
public void show() {
System.out.println("具体产品1显示...");
}
}
//具体产品2:实现抽象产品中的抽象方法
class ConcreteProduct2 implements Product {
public void show() {
System.out.println("具体产品2显示...");
}
}
//抽象工厂:提供了厂品的生成方法
interface AbstractFactory {
public Product newProduct();
}
//具体工厂1:实现了厂品的生成方法
class ConcreteFactory1 implements AbstractFactory {
public Product newProduct() {
System.out.println("具体工厂1生成-->具体产品1...");
return new ConcreteProduct1();
}
}
//具体工厂2:实现了厂品的生成方法
class ConcreteFactory2 implements AbstractFactory {
public Product newProduct() {
System.out.println("具体工厂2生成-->具体产品2...");
return new ConcreteProduct2();
}
}
抽象工厂
创建相关或依赖对象的家族,而无需明确指定具体类。
代理模式
特点
为其他对象提供一个代理以便控制这个对象的访问。
应用场景
- Spring的AOP机制就是采用动态代理的机制来实现切面编程
- Hibernate中延时加载的实现
- Mybatis中实现拦截器插件
静态代理
由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
public class ProxyTest {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.Request();
}
}
//抽象主题
interface Subject {
void Request();
}
//真实主题
class RealSubject implements Subject {
public void Request() {
System.out.println("访问真实主题方法...");
}
}
//代理
class Proxy implements Subject {
private RealSubject realSubject;
public void Request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
preRequest();
realSubject.Request();
postRequest();
}
public void preRequest() {
System.out.println("访问真实主题之前的预处理。");
}
public void postRequest() {
System.out.println("访问真实主题之后的后续处理。");
}
}
运行结果:
访问真实主题之前的预处理。
访问真实主题方法...
访问真实主题之后的后续处理。
动态代理
基于接口的动态代理
被代理类最少实现一个接口,使用JDK的Proxy
public class JdkTest {
public static void main(String[] args) {
Producer producer = new Producer();
IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(
producer.getClass().getClassLoader(),
producer.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object invoke = method.invoke(producer, args);
System.out.println("after");
return invoke;
}
}
);
proxyProducer.say();
}
}
interface IProducer {
void say();
}
class Producer implements IProducer {
@Override
public void say() {
System.out.println("真实对象say");
}
}
运行结果:
before
真实对象say
after
基于子类的动态代理
使用Cglib的Enhancer
public class CglibTest {
public static void main(String[] args) {
Producer producer = (Producer) Enhancer.create(Producer.class, new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before");
Object res = methodProxy.invokeSuper(o, args);
System.out.println("after");
return res;
}
});
producer.say();
}
}
class Producer {
public void say() {
System.out.println("真实对象say");
}
}
运行结果:
before
真实对象say
after
模板方法模式
特点
定义一个算法结构,而将一些步骤延迟到子类实现。
应用场景
- 数据库访问的封装
- Junit单元测试
- Servlet中关于doGet/doPost方法的调用
- Hibernate中模板程序
- Spring中JDBCTemplate,HibernateTemplate
public class TemplateTest {
public static void main(String[] args) {
DrawMoney dm = new DrawMoney();
dm.process();
}
}
abstract class BankTemplateMethod {
//1.取号排队
public void takeNumber() {
System.out.println("取号排队。。");
}
// 2.每个子类不同的业务实现,由各自子类实现.
abstract void transact();
// 3.评价
public void evaluate() {
System.out.println("反馈评价。。");
}
public void process() {
takeNumber();
transact();
evaluate();
}
}
class DrawMoney extends BankTemplateMethod {
@Override
void transact() {
System.out.println("我要取款");
}
}
适配器模式
特点
将一个类的方法接口转换成客户希望的另外一个接口。
应用场景
- java.io.InputStreamReader(InputStream)
- java.io.OutputStreamWriter(OutputStream)
- SpringMVC中HandlerAdapter
类适配器
public class ClassAdapterTest {
public static void main(String[] args) {
System.out.println("类适配器模式测试:");
Target target = new ClassAdapter();
target.request();
}
}
//目标接口
interface Target {
public void request();
}
//适配者接口
class Adaptee {
public void specificRequest() {
System.out.println("适配者中的业务代码被调用!");
}
}
//类适配器类
class ClassAdapter extends Adaptee implements Target {
@Override
public void request() {
super.specificRequest();
}
}
对象适配器
public class ObjectAdapterTest {
public static void main(String[] args) {
System.out.println("对象适配器模式测试:");
Adaptee adaptee = new Adaptee();
Target target = new ObjectAdapter(adaptee);
target.request();
}
}
//目标接口
interface Target {
public void request();
}
//适配者接口
class Adaptee {
public void specificRequest() {
System.out.println("适配者中的业务代码被调用!");
}
}
class ObjectAdapter implements Target {
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
外观模式
特点
对外提供一个统一的方法,来访问子系统中的一群接口。
public class FacadePattern {
public static void main(String[] args) {
Facade f = new Facade();
f.method();
}
}
class Facade {
private SubSystem01 obj1 = new SubSystem01();
private SubSystem02 obj2 = new SubSystem02();
private SubSystem03 obj3 = new SubSystem03();
public void method() {
obj1.method1();
obj2.method2();
obj3.method3();
}
}
//子系统
class SubSystem01 {
public void method1() {
System.out.println("子系统01的method1()被调用!");
}
}
//子系统
class SubSystem02 {
public void method2() {
System.out.println("子系统02的method2()被调用!");
}
}
//子系统
class SubSystem03 {
public void method3() {
System.out.println("子系统03的method3()被调用!");
}
}
运行结果:
子系统01的method1()被调用!
子系统02的method2()被调用!
子系统03的method3()被调用!
原型模式
特点
通过复制现有的实例来创建新的实例。
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Realizetype obj1 = new Realizetype();
Realizetype obj2 = (Realizetype) obj1.clone();
System.out.println("obj1==obj2?" + (obj1 == obj2));
}
}
class Realizetype implements Cloneable {
Realizetype() {
System.out.println("具体原型创建成功!");
}
@Override
protected Object clone() throws CloneNotSupportedException {
System.out.println("具体原型复制成功!");
return (Realizetype) super.clone();
}
}
运行结果:
具体原型创建成功!
具体原型复制成功!
obj1==obj2?false
装饰模式
特点
动态的给对象添加新的功能。
应用场景
- IO中输入流和输出流的设计
- Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper类,增强了request对象的功能。
- Struts2中,request,response,session对象的处理
public class DecoratorPattern {
public static void main(String[] args) {
Component p = new ConcreteComponent();
p.operation();
System.out.println("---------------------------------");
Component d = new ConcreteDecorator(p);
d.operation();
}
}
//抽象构件角色
interface Component {
void operation();
}
//具体构件角色
class ConcreteComponent implements Component {
public ConcreteComponent() {
System.out.println("创建具体构件角色");
}
@Override
public void operation() {
}
}
//抽象装饰角色
class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
//具体装饰角色
class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addedFunction();
}
public void addedFunction() {
System.out.println("为具体构件角色增加额外的功能addedFunction()");
}
}
运行结果:
创建具体构件角色
---------------------------------
为具体构件角色增加额外的功能addedFunction()
策略模式
特点
定义一系列算法,把他们封装起来,并且使它们可以相互替换。
应用场景
Spring框架中,Resource接口,资源访问策略
public class StrategyTest {
public static void main(String[] args) {
System.out.println(StrategyTest.getPrice("小顾客", 1000));
System.out.println(StrategyTest.getPrice("大顾客", 1000));
System.out.println(StrategyTest.getPrice("老顾客", 1000));
}
public static double getPrice(String type, double price) {
if ("小顾客".equals(type)) {
System.out.println("不打折");
return price;
} else if ("大顾客".equals(type)) {
System.out.println("打9折");
return price * 0.9;
} else if ("老顾客".equals(type)) {
System.out.println("打8折");
return price * 0.8;
}
return price;
}
}
运行结果:
不打折
1000.0
打9折
900.0
打8折
800.0
观察者模式
特点
对象间的一对多的依赖关系。
应用场景
Spring 事件驱动模型就是观察者模式很经典的⼀个应⽤。
public class ObserverPattern {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer ob1 = new ConcreteObserver1();
Observer ob2 = new ConcreteObserver2();
subject.add(ob1);
subject.add(ob2);
subject.notifyObserver();
}
}
//抽象目标
abstract class Subject {
protected List<Observer> observers = new ArrayList<Observer>();
//增加观察者方法
public void add(Observer observer) {
observers.add(observer);
}
//删除观察者方法
public void delete(Observer observer) {
observers.remove(observer);
}
//通知观察者方法
public abstract void notifyObserver();
}
//具体目标
class ConcreteSubject extends Subject {
@Override
public void notifyObserver() {
System.out.println("具体目标发生改变...");
System.out.println("--------------");
for (Observer observer : observers) {
observer.response();
}
}
}
//抽象观察者
interface Observer {
void response();
}
//具体观察者1
class ConcreteObserver1 implements Observer {
public void response() {
System.out.println("具体观察者1作出反应!");
}
}
//具体观察者1
class ConcreteObserver2 implements Observer {
public void response() {
System.out.println("具体观察者2作出反应!");
}
}
运行结果:
具体目标发生改变...
--------------
具体观察者1作出反应!
具体观察者2作出反应!