设计模式

设计模式是学习及工作面试中不可忽略的重要知识点,这里简单概括了23种设计模式的应用场景,例如单例的8种写法。在今后的工作中多加思考应用。

设计模式

  • 指导思想
    • 可维护性
    • 可复用性
    • 可扩展性
    • 灵活性
  • 面向对象六大原则
    • 单一职责原则(SRP)
      • 低耦合高内聚
    • 开闭原则(OCP)
      • 对扩展开放 对修改关闭
    • 里式替换原则(LSP)
      • 子类可以透明替换父类
    • 依赖倒置原则(DIP)
      • 面向接口编程
      • 面向抽象编程
    • 接口隔离原则(ISP)
      • 接口职责单一
    • 迪米特法则(LoD)
      • 降低耦合
  • Intepreter(解释器)
    • 动态脚本解析
  • State(状态)
    • 动作根据状态的不同而不同
    • TCP Coonnection
      • open
      • close
      • aknowledge
    • 有限状态机(FSM)
  • TemplateMethod(模板方法),钩子函数
    • 重写
    • classloader
  • 备忘录(Memento)
    • 记录快照
    • 存盘
    • transient(透明),不进行序列化
  • 原型/克隆(Prototype)
    • BeanUtils.copyProperties
    • clone
      • 实现cloneable接口
      • 重写clone方法
      • 效率并不一定比new高
    • 自带
  • 命令(Command/Action/Transaction)
    • do
    • undo
    • 多次undo:command+cor
    • 宏:command+组合
  • 桥接(Bridge)
    • 用聚合代替继承
      • 桥接(Bridge)
    • Gift(聚合GiftImpl)
      • WarmGift、HotGift
  • 适配器(Adapter)
    • asm的classreader和classwriter
    • io流
    • ODBC-JDBC Bridge
    • 常见的Adapter例如WindowAdapter不是Adapter模式
  • 构建器(Builder)
    • 链式编程
    • 静态内部类构件对象
      • 必要的属性放在构造方法中
  • 访问者(Visitor)
    • 结构固定的一些对象
    • 应用在编译器
    • 特殊的设计模式
    • javap
      • 观察反编译的class文件:变量,方法
      • 类的初始化:idea->show->bytecode
    • asm
  • 迭代器(Iterator)
    • 物理层面
      • 数组/链表
    • 逻辑结构
      • stack、queue、tree
  • 代理(Proxy)
    • 类似装饰者
    • 分离代理行为和被代理对象,提被代理对象干某件事情
    • JDK动态代理
      • invoke
        • Proxy.newProxyInstance(T.class.getClassLoader(),new Class[]{接口.class},handler)
        • 缺陷在于必须实现接口
    • Cglib
      • interceptor
        • 缺陷:被代理类如果是final的话,不能进行动态代理
    • Instrument修改字节码
    • 反射:通过字节码分析类的属性和方法
    • 底层由asm实现:直接操纵二进制码
      • 动态语言,无所不能
    • Aop
      • IOC+AOP(Bean工厂+动态配置+行为灵活拼接)
  • 享元(Flyweight)
    • 共享元数据
    • 多个子弹池子(用就拿)
    • 类似连接池、线程池
    • 池化思想
    • java中的String用的就是享元模式
  • 组合(Composite)
    • 树形结构专用
  • 责任链模式(Chain of responsibility)
  • 装饰者(Decorator)
  • 观察者(Observer)
    • 与责任链很像
    • 继承Observer接口
    • 观察者根据被观察者的事件做出的反应
    • Spring Aop切面
    • 时间Event接口
    • 前端事件
    • hook,callback,handle,listener
  • 门面(Facade)
    • 对外
  • 调停者(Mediator)
    • 对内
      • 消息中间件
  • 策略
    • 开放接口,反射注入全路径名
    • 对更改关闭,对扩展开放
    • Class.forName.getDeclaredConstructor().newInstance();
  • 单例(8种)
    • 枚举类:枚举
    • 饿汉式private static final Mgr01 INSTANCE = new Mgr01();简单实用
      • 缺点:不管用到与否,类装载时就完成实例化
    • static {INSTANCE = new Mgr02();}跟上一种一个意思
    • 懒汉式
      • 虽然达到了按需初始化的目的,但却带来线程不安全的问题
    • 加synchronized
      • 效率下降
    • 减小同步代码块的方式提高效率(不可行)
    • 双重检查
    • 加载外部类时不会加载内部类,这样可以实现懒加载
    • 不仅可以解决线程同步,还可以防止反序列化。
      • public enum Mgr08 {
  • 工厂
    • 简单工厂(任意定制交通工具)
      • 扩展性不好
      • new Factory.createCar()
      • new Factory.createPlane()
    • 静态工厂
    • 工厂方法(任意定制生产过程)
      • new CarFactory.create()
    • 抽象工厂
      • ModernFactory,MagicFactory
        • abstract Factory(创建武器,车,食物)
      • 形容词用接口,名词用抽象类

指导思想

可维护性

可复用性

可扩展性

灵活性

面向对象六大原则

单一职责原则(SRP)

低耦合高内聚

开闭原则(OCP)

对扩展开放 对修改关闭

里式替换原则(LSP)

子类可以透明替换父类

依赖倒置原则(DIP)

面向接口编程

面向抽象编程

接口隔离原则(ISP)

接口职责单一

迪米特法则(LoD)

降低耦合

Intepreter(解释器)

动态脚本解析

State(状态)

动作根据状态的不同而不同

TCP Coonnection

open

close

aknowledge

有限状态机(FSM)

TemplateMethod(模板方法),钩子函数

重写

classloader

备忘录(Memento)

记录快照

存盘

transient(透明),不进行序列化

原型/克隆(Prototype)

BeanUtils.copyProperties

clone

实现cloneable接口

重写clone方法

效率并不一定比new高

自带

命令(Command/Action/Transaction)

do

undo

多次undo:command+cor

宏:command+组合

桥接(Bridge)

用聚合代替继承

桥接(Bridge)

Gift(聚合GiftImpl)

WarmGift、HotGift

适配器(Adapter)

asm的classreader和classwriter

io流

ODBC-JDBC Bridge

常见的Adapter例如WindowAdapter不是Adapter模式

构建器(Builder)

链式编程

静态内部类构件对象

必要的属性放在构造方法中

访问者(Visitor)

结构固定的一些对象

应用在编译器

特殊的设计模式

javap

观察反编译的class文件:变量,方法

类的初始化:idea->show->bytecode

asm

迭代器(Iterator)

物理层面

数组/链表

逻辑结构

stack、queue、tree

代理(Proxy)

类似装饰者

分离代理行为和被代理对象,提被代理对象干某件事情

JDK动态代理

invoke

Proxy.newProxyInstance(T.class.getClassLoader(),new Class[]{接口.class},handler)

缺陷在于必须实现接口

Cglib

interceptor

缺陷:被代理类如果是final的话,不能进行动态代理

Instrument修改字节码

反射:通过字节码分析类的属性和方法

底层由asm实现:直接操纵二进制码

动态语言,无所不能

Aop

IOC+AOP(Bean工厂+动态配置+行为灵活拼接)

享元(Flyweight)

共享元数据

多个子弹池子(用就拿)

类似连接池、线程池

池化思想

java中的String用的就是享元模式

组合(Composite)

树形结构专用

责任链模式(Chain of responsibility)

装饰者(Decorator)

观察者(Observer)

与责任链很像

继承Observer接口

观察者根据被观察者的事件做出的反应

Spring Aop切面

时间Event接口

前端事件

hook,callback,handle,listener

门面(Facade)

对外

调停者(Mediator)

对内

消息中间件

策略

开放接口,反射注入全路径名

对更改关闭,对扩展开放

Class.forName.getDeclaredConstructor().newInstance();

单例(8种)

枚举类:枚举

饿汉式private static final Mgr01 INSTANCE = new Mgr01();简单实用

缺点:不管用到与否,类装载时就完成实例化

static {INSTANCE = new Mgr02();}跟上一种一个意思

懒汉式

虽然达到了按需初始化的目的,但却带来线程不安全的问题

加synchronized

效率下降

public class Mgr04 {
private static Mgr04 INSTANCE;

private Mgr04() {
}

public static synchronized Mgr04 getInstance() {
    if (INSTANCE == null) {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        INSTANCE = new Mgr04();
    }
    return INSTANCE;
}

public void m() {
    System.out.println("m");
}

public static void main(String[] args) {
    for(int i=0; i<100; i++) {
        new Thread(()->{
            System.out.println(Mgr04.getInstance().hashCode());
        }).start();
    }
}

}

减小同步代码块的方式提高效率(不可行)

public class Mgr05 {
private static Mgr05 INSTANCE;

private Mgr05() {
}

public static Mgr05 getInstance() {
    if (INSTANCE == null) {
        //妄图通过减小同步代码块的方式提高效率,然后不可行
        synchronized (Mgr05.class) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Mgr05();
        }
    }
    return INSTANCE;
}

public void m() {
    System.out.println("m");
}

public static void main(String[] args) {
    for(int i=0; i<100; i++) {
        new Thread(()->{
            System.out.println(Mgr05.getInstance().hashCode());
        }).start();
    }
}

}

双重检查

public class Mgr06 {
private static volatile Mgr06 INSTANCE; //JIT

private Mgr06() {
}

public static Mgr06 getInstance() {
    if (INSTANCE == null) {
        //双重检查
        synchronized (Mgr06.class) {
            if(INSTANCE == null) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                INSTANCE = new Mgr06();
            }
        }
    }
    return INSTANCE;
}

public void m() {
    System.out.println("m");
}

public static void main(String[] args) {
    for(int i=0; i<100; i++) {
        new Thread(()->{
            System.out.println(Mgr06.getInstance().hashCode());
        }).start();
    }
}

}

加载外部类时不会加载内部类,这样可以实现懒加载

public class Mgr07 {

private Mgr07() {
}

private static class Mgr07Holder {
    private final static Mgr07 INSTANCE = new Mgr07();
}

public static Mgr07 getInstance() {
    return Mgr07Holder.INSTANCE;
}

public void m() {
    System.out.println("m");
}

public static void main(String[] args) {
    for(int i=0; i<100; i++) {
        new Thread(()->{
            System.out.println(Mgr07.getInstance().hashCode());
        }).start();
    }
}

}

不仅可以解决线程同步,还可以防止反序列化。

public enum Mgr08 {

INSTANCE;

public void m() {}

public static void main(String[] args) {
    for(int i=0; i<100; i++) {
        new Thread(()->{
            System.out.println(Mgr08.INSTANCE.hashCode());
        }).start();
    }
}

}

工厂

简单工厂(任意定制交通工具)

扩展性不好

new Factory.createCar()

new Factory.createPlane()

静态工厂

工厂方法(任意定制生产过程)

new CarFactory.create()

抽象工厂

ModernFactory,MagicFactory

abstract Factory(创建武器,车,食物)

形容词用接口,名词用抽象类

你可能感兴趣的:(学习,java)