设计模式
设计模式有23种,分为以下三大类:
创建型模式
共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式
共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式
共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
单例模式
在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。
单例模式的特点:
- 单例类只有一个实例对象;
- 该单例对象必须由单例类自行创建;
- 单例类对外提供一个访问该单例的全局访问点;
单例中有两种常见的模式:懒汉式、饿汉式。
单例懒汉式
public class DanLilazy {
// 懒加载
private static DanLilazy instance;
// private 避免类在外部被实例化
private DanLilazy() {}
// 动态工厂方法创建实例
public static DanLilazy getInstance() {
if (null == instanc7e) {
synchronized (DanLilazy.class) {
if (instance == null) {
instance = new DanLilazy();
}
}
}
return instance;
}
}
单例饿汉式
public class DanliHungry {
private static DanliHungry instance = new DanliHungry();
// private 避免类在外部被实例化
private DanliHungry(){}
public static DanliHungry getInstance() {
return instance;
}
}
工厂模式
将创建对象的逻辑(操作),向客户隐藏,只暴露给可以一个接口(方法),客户调用该接口(方法)就能够得到对应的对象
工厂的职责:创建产品(对象)
核心:封装(隐藏对象创建的细节)
例 [发送邮件和短信](抽象工厂模式):
定义接口
/**
* 发送者
*/
public interface Sender {
public void send();
}
实现类
/**
* 邮件类
*/
public class MailSender implements Sender {
@Override
public void send() {
System.out.println("发送邮件。。。");
}
}
/**
* 短信类
*/
public class SmsSebder implements Sender {
@Override
public void send() {
System.out.println("发送短信。。。");
}
}
工厂接口
/**
* 发送接口
*/
public interface SendFactory {
/**
* 发送方法
* @return 发送对象
*/
public Sender produce();
}
工厂实现类
/**
* 邮箱工厂
*/
public class MailFactory implements SendFactory {
@Override
public Sender produce() {
return new MailSender();
}
}
/**
* 短信工厂
*/
public class SmsFactory implements SendFactory {
@Override
public Sender produce() {
return new SmsSebder();
}
}
测试类
/**
* 工厂模式
*/
public class Test {
public static void main(String[] args) {
SendFactory sf = new MailFactory();
Sender produce = sf.produce();
produce.send();
}
}
模板方法模式
父类(接口)定义了一个软件业务的核心逻辑,该逻辑由一些列的行为(方法or步骤)组成,父类定义了一个模板,至于模板里面的每个行为(步骤)由子类去实现。
模板方法(Template Method)模式的定义如下:
定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
例 [绘画的行为和清除]:
接口
public interface Shape {
// 绘制方法
public void draw();
// 清除方法
public void clean();
/**
* 模板方法:规定了先绘画形状,然后再清除形状
* 该方法可以让每个实现了Shape接口的子类去调用
*/
public default void Action(){
draw();
clean();
}
}
实现类
/**
* 圆形功能
*/
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆形,,,");
}
@Override
public void clean() {
System.out.println("清除圆形。。。");
}
}
/**
* 三角形功能
*/
public class Trigon implements Shape {
@Override
public void draw() {
System.out.println("绘制三角形,,,");
}
@Override
public void clean() {
System.out.println("清除三角形。。。");
}
}
测试类
/**
* 模板模式
*/
public class Test {
public static void main(String[] args) {
Circle circle = new Circle();
circle.draw();
}
}
代理模式
代理模式的定义:
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
代理模式的主要优点:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;
其主要缺点:
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度;
静态代理
例 [买房子]:
接口
/**
* 购买房子
*/
public interface BuyHouse {
void buyHouse();
}
实现类
public class BuyHouseImpl implements BuyHouse {
@Override
public void buyHouse() {
System.out.println("购买房子");
}
}
代理类
public class BuyHouseProxy implements BuyHouse {
private BuyHouse BuyHouse;
public BuyHouse getBuyHouse() {
return BuyHouse;
}
public void setBuyHouse(BuyHouse buyHouse) {
BuyHouse = buyHouse;
}
public BuyHouseProxy(BuyHouse buyHouse) {
this.BuyHouse = buyHouse;
}
@Override
public void buyHouse() {
System.out.println("买房前准备,,,");
BuyHouse.buyHouse();
System.out.println("买房后装修,,,");
}
}
测试类
public class TestStaticProxy {
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImpl();
BuyHouseProxy buyHouseProxy = new BuyHouseProxy(buyHouse);
buyHouseProxy.buyHouse();
}
}
动态代理
接口
/**
* 购买房子
*/
public interface BuyHouse {
void buyHouse();
}
实现类
public class BuyHouseImpl implements BuyHouse {
@Override
public void buyHouse() {
System.out.println("购买房子");
}
}
代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxyHandler<T> implements InvocationHandler {
private T type;
public DynamicProxyHandler(T type) {
this.type = type;
}
/**
* 创建代理类型对象
* @return 代理对象
*/
@SuppressWarnings("unchecked")
public T createProxy() {
// 创建动态代理的对象
return (T) Proxy.newProxyInstance(type.getClass().getClassLoader(), type.getClass().getInterfaces(), this);
}
/**
* 动态代理调用buyHouse()方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("买房前准备,,,");
Object result = method.invoke(type, args);
System.out.println("买房后装修,,,");
return result;
}
}
测试类
public class TestDynamicProxy {
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImpl();
DynamicProxyHandler<BuyHouse> handler = new DynamicProxyHandler<>(buyHouse);
BuyHouse createProxy = handler.createProxy();
createProxy.buyHouse();
}
}
参照(CSDN-终点):https://blog.csdn.net/zhangerqing/article/details/8194653
Java设计模式:23种设计模式全面解析(超级详细):http://c.biancheng.net/design_pattern/