目录
什么是设计模式?
设计模式是一种可复用性较高的软件设计解决方案。它描述了在某些情境下,针对特定问题的可重用的设计思路和解决方案。设计模式旨在提高代码重用度、可读性、可维护性、可扩展性和可靠性。
优点:
1. 提高代码的重用性和可维护性。
2. 提高系统的可扩展性和灵活性。
3. 提高代码的可读性和可理解性。
4. 降低代码的耦合度。
5. 提高代码的稳定性和安全性。
6. 促进软件设计的标准化和规范化。
设计模式分为三类:
1. 创建型模式:涉及到对象创建的机制,以合适的方式来创建对象,并且可以根据不同的情况使用不同的创建方式,以达到最优的设计效果。
2. 结构型模式:涉及到类和对象的组合,以形成更大的结构。
3. 行为型模式:涉及到对象之间的通信,以及调度它们之间的职责。
下面列举一些常见的设计模式:
1. 创建型模式
- 工厂方法模式(Factory Method Pattern)
- 抽象工厂模式(Abstract Factory Pattern)
- 单例模式(Singleton Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype Pattern)
2. 结构型模式
- 适配器模式(Adapter Pattern)
- 桥接模式(Bridge Pattern)
- 装饰者模式(Decorator Pattern)
- 组合模式(Composite Pattern)
- 外观模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
3. 行为型模式
- 策略模式(Strategy Pattern)
- 模板方法模式(Template Method Pattern)
- 观察者模式(Observer Pattern)
- 迭代器模式(Iterator Pattern)
- 职责链模式(Chain of Responsibility Pattern)
- 命令模式(Command Pattern)
- 备忘录模式(Memento Pattern)
- 状态模式(State Pattern)
- 访问者模式(Visitor Pattern)
- 中介者模式(Mediator Pattern)
- 解释器模式(Interpreter Pattern)
单例模式:
确保程序在运行过程中只会只能创建一个实例。
步骤:
1、声明静态引用
2、私有化构造方法
3、提供公共方法获取当前对象
饿汉式单例:
/**
* @Author {那蓝桉}
* @Date: 2023/05/16/ 17:39
* @description 饿汉式单例,线程安全,最开始就直接开辟一块内存,存放对象
*/
public class Sg1 {
//创建唯一实例
private static final Sg1 instance = new Sg1();
//私有化构造方法
private Sg1(){}
//定义公共的访问接口
public static Sg1 getInstance(){
return instance;
}
}
静态内部类的方式:
/**
* @Author {那蓝桉}
* @Date: 2023/05/16/ 17:39
* @description 饿汉式单例,静态内部类
*/
public class Sg5 {
private static class Holder{
//创建唯一实例
private static final Sg5 instance = new Sg5();
}
//私有化构造方法
private Sg5(){
System.out.println("hi");
}
//定义公共的访问接口
public static Sg5 getInstance(){
return Holder.instance;
}
}
枚举:
/**
* @Author {那蓝桉}
* @Date: 2023/05/16/ 20:38
* @description 枚举
*/
public enum Sg6 {
instance;
}
懒汉式单例:
/**
* @Author {那蓝桉}
* @Date: 2023/05/16/ 17:39
* @description 懒汉式单例,线程不安全,用的时候创建对象
*/
public class Sg2 {
//创建唯一实例
private static Sg2 instance;
//私有化构造方法
private Sg2(){}
//定义公共的访问接口
public static Sg2 getInstance(){
if(instance==null) {
//延时加载
instance = new Sg2();
}
return instance;
}
}
线程安全的懒汉式单例:
/**
* @Author {那蓝桉}
* @Date: 2023/05/16/ 17:39
* @description 懒汉式单例,加锁,线程安全,调用效率低
*/
public class Sg3 {
//创建唯一实例
private static Sg3 instance;
//私有化构造方法
private Sg3(){}
//定义公共的访问接口
public static synchronized Sg3 getInstance(){
if(instance==null) {
//延时加载
instance = new Sg3();
}
return instance;
}
}
双重检查锁:
/**
* @Author {那蓝桉}
* @Date: 2023/05/16/ 17:39
* @description 懒汉式单例,双重检查锁,volatile保证变量的可见性
*/
public class Sg4 {
//创建唯一实例
private static volatile Sg4 instance;
//私有化构造方法
private Sg4(){}
//定义公共的访问接口
public static Sg4 getInstance(){
//如果对象为null才需要加锁,提高了效率
if(instance==null) {
//如果线程A获取锁后,线程B正在等待获取锁时
synchronized (Sg4.class) {
//线程A如果不判断直接创建对象,之后释放锁
//线程B获取锁后也会直接创建对象,导致对象不一样
//所以需要加null值判断
if(instance==null) {
//延时加载
instance = new Sg4();
}
}
}
return instance;
}
}
测试:
/**
* @Author {那蓝桉}
* @Date: 2023/05/16/ 17:39
* @description
*/
public class Test1 {
@Test
public void test1(){
Sg1 m1 = Sg1.getInstance();
Sg1 m2 = Sg1.getInstance();
System.out.println(m1==m2);//true
Assert.assertEquals(m1,m2);
}
@Test
public void test2(){
Sg2 m1= Sg2.getInstance();
Sg2 m2= Sg2.getInstance();
Assert.assertEquals(m1,m2);
}
@Test
public void test3(){
Sg3 m1= Sg3.getInstance();
Sg3 m2= Sg3.getInstance();
Assert.assertEquals(m1,m2);
new Thread(()->{
Sg3 m3 = Sg3.getInstance();
System.out.println(m3);
}).start();
new Thread(()->{
Sg3 m4 = Sg3.getInstance();
System.out.println(m4);
}).start();
}
@Test
public void test4(){
new Thread(()->{
Sg3 m1 = Sg3.getInstance();
System.out.println(m1);
}).start();
new Thread(()->{
Sg3 m2 = Sg3.getInstance();
System.out.println(m2);
}).start();
}
@Test
public void test5(){
Sg5 m1 = Sg5.getInstance();
Sg5 m2 = Sg5.getInstance();
System.out.println(m1);
System.out.println(m2);
}
@Test
public void test6(){
Assert.assertEquals(Sg6.instance,Sg6.instance);
}
}
工厂模式:
public abstract class AbstractFactory {
abstract Cake create();
}
public interface Cake {
void show();
}
public class EggFactory extends AbstractFactory{
@Override
Cake create() {
return new EggCake();
}
}
public class HandFactory extends AbstractFactory{
@Override
Cake create() {
return new HandCake();
}
}
public class EggCake implements Cake{
@Override
public void show() {
System.out.println("鸡蛋饼来咯");
}
}
public class HandCake implements Cake{
@Override
public void show() {
System.out.println("手抓饼来咯");
}
}
public class Client {
public static void main(String[] args) {
AbstractFactory factory = new EggFactory();
Cake cake = factory.create();
cake.show();
AbstractFactory factory1 = new HandFactory();
Cake cake1 = factory1.create();
cake1.show();
}
}
代理模式:
动态代理:
在过程中动态创建代理对象,动态生成class文件
1、JDK动态代理
2、CGLIB动态代理
JDK动态代理:
public interface UserService {
void query();
void add();
}
public class UserServiceImpl implements UserService {
@Override
public void query() {
System.out.println("查询正在进行");
}
@Override
public void add() {
System.out.println("录入正在进行");
}
}
public class TestProxy {
public static void main(String[] args) {
UserService target = new UserServiceImpl();
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始记录日志");
Object res = method.invoke(target, args);
System.out.println("日志记录结束");
return res;
}
}
);
proxy.query();
proxy.add();
}
}
CGLIB动态代理:
public class CglibProxy {
private Object target;
public CglibProxy(Object target) {
this.target = target;
}
//生成代理对象,是目标类的子类
public Object getProxy(){
//创建增强类的对象
Enhancer enhancer = new Enhancer();
//设置父类型
enhancer.setSuperclass(target.getClass());
//MethodInterceptor:方法拦截器
enhancer.setCallback(new MethodInterceptor() {
//method:目标方法
//objects:目标方法的参数
//methodProxy:目标方法的代理
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("接着扩充功能");
//调用目标方法并返回结果
Object res = methodProxy.invoke(target, objects);
System.out.println("继续扩充");
return res;
}
});
//返回生成的代理对象
return enhancer.create();
}
}
public class TestCglib {
public static void main(String[] args) {
//目标对象
UserService service = new UserServiceImpl();
UserService proxy = (UserService) new CglibProxy(service).getProxy();
proxy.query();
}
}