一、23种设计模式速记口诀
http://c.biancheng.net/view/1327.html
https://blog.youkuaiyun.com/baidu_33221362/article/details/113444797
23种设计模式的分类
《观迭策》
抽工建单原, 创建型(5)
适桥外装组; 结构型(7)
代享解模责, 行为行模式(11)从解开始,包含题目
备状访命中。
速记小故事
领导抽调一个工人去建设一个单****元,心中不悦
把一个适当的桥放在外面组装,
由于心中不悦,代享(这个工人)把桥的模型拆解了,怕领导责骂,
于是准备好了罪状去领导那里访问自己的命运,此时正在去的途中。
题目:心中惴惴不安写下了这首诗,诗名的意思是:观察自己迭迭荡荡的工作,该如何制定策略解决(桥被拆解的问题)
二、设计模式的7大原则
- 单一职责原则 一个类只应该负责一个职责(不是指一个方法),例如订单类就应该只负责下单订单,撤订单的功能,而不能负责减库存的功能。
- 接口隔离原则 在A类中依赖B类时应该尽量用B类的接口作为参数去依赖,如果A类中不能用到B类中的所有方法是,要将B类的接口拆分成多个。
- 依赖倒置原则 A类依赖B类是,要去依赖B类的接口,而不要直接依赖B类。
- 里氏替换原则 这个原则,主要是对继承的一些限制子类可以扩展父类的功能,但不能改变父类原有的功能
- 开闭原则 (OCP原则) :★ 软件实体应当对扩展开放,对修改关闭,这就是开闭原则的经典定义
- 迪米特原则:只与你的直接朋友交谈,不跟“陌生人”说话,什么是直接朋友:当前对象本身、当前对象的成员对象(通过getset方法设置的)、当前对象所创建的对象(直接在对象中定义并new出来的)、当前对象的方法参数等(通过参数传入的),这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法
- 聚合复用原则:要尽量先使用组合(private User user= new User())或者聚合(private定义getset方法)等关联(方法中通过参数传入的)关系来实现,其次才考虑使用继承关系来实现,如果要使用继承关系,则必须严格遵循里氏替换原则。合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。
三、UML类图
3.1 uml的用途
用于描述系统中的类(对象)用类(对象)之间的关系。类之间的关系包括
- 依赖(Dependency) 如果在类中用到了对方就是依赖
- 泛化(继承)依赖关系的特例
- 实现 (Generalization)实现接口,依赖关系的特例
- 关联(Association)单上和双向 一对一还是一对多还是多对多的关系 依赖关系的特例
- 聚合(Aggregation)getset方法实现,与主类可分开
- 组合(Composite) 类中的变量直接new出来的,注意不是在方法中,而是类的成员变量
与主类不可分开
uml中的关系
四、23中涉及模式
4.1 单例
* 在整个软件中只有一个实例对象8中,第6中没写
* 饿汉式(静态变量,可以使用,内存的浪费)
* 饿汉式(静态代码块,可以使用,内存的浪费)
* 懒汉式(线程不安全写法,不要使用)
* 懒汉式(线程安全写法,不推荐使用,效率低)
* ★双重验证
* ★静态内部类
* ★枚举(优点:防止反序列化)
* 使用场景:
* 频繁进行创建和销毁的对象,创建对象时好时过多或耗费资源过多,但又经常使用的
* 工具类
* 频繁访问数据库或文件的对象(数据源,session工厂)
* JDK中:Runtime类就是单例模式
package com.esint.boot.designGOF23;
/**
* @author maruis
* 在整个软件中只有一个实例对象8中,第6中没写
* 饿汉式(静态变量,可以使用,内存的浪费)
* 饿汉式(静态代码块,可以使用,内存的浪费)
* 懒汉式(线程不安全写法,不要使用)
* 懒汉式(线程安全写法,不推荐使用,效率低)
* ★双重验证
* ★静态内部类
* ★枚举(优点:防止反序列化)
* 使用场景:
* 频繁进行创建和销毁的对象,创建对象时好时过多或耗费资源过多,但又经常使用的
* 工具类
* 频繁访问数据库或文件的对象(数据源,session工厂)
* JDK中:Runtime类就是单例模式
*/
public class 单例模式 {
public static void main(String[] args) {
// 测试
SingleTon ton1 = SingleTon.getInstance();
SingleTon ton2 = SingleTon.getInstance();
System.out.println("maruis----这个两个实例是否相同-->" + (ton1 == ton2));
System.out.println("maruis---ton1--hashcode->" + ton1.hashCode());
System.out.println("maruis---ton2--hashcode->" + ton2.hashCode());
System.out.println("maruis------>" + "############################");
System.out.println("maruis--饿汉式--这个两个实例是否相同-->" + (SingleTon02.getInstance() == SingleTon02.getInstance()));
System.out.println("maruis--懒汉式线程不安全--这个两个实例是否相同-->" + (SingleTon03.getInstance() == SingleTon03.getInstance()));
System.out.println("maruis--懒汉式线程安全写法--这个两个实例是否相同-->" + (SingleTon04.getInstance() == SingleTon04.getInstance()));
System.out.println("maruis--懒汉式线程安全写法(★推荐使用)--这个两个实例是否相同-->" + (SingleTon06.getInstance() == SingleTon06.getInstance()));
System.out.println("maruis--静态内部类(★推荐使用)--这个两个实例是否相同-->" + (SingleTon07.getInstance() == SingleTon07.getInstance()));
System.out.println("maruis--枚举(★推荐使用)--这个两个实例是否相同-->" + (SingleTon08.INSTANCE == SingleTon08.INSTANCE));
SingleTon08.INSTANCE.sayOk();
}
}
/**
* 饿汉式(静态变量)
* 缺点,在类加载时就会被调用,可能造成内存的浪费
*/
class SingleTon {
// 1. 构造器私有化 外部不能new
private SingleTon() {
}
// 2.本类内部创建对象实例
private final static SingleTon intance = new SingleTon();
// 3.提供一个共有的静态方法,返回实例对象
public static SingleTon getInstance() {
return intance;
}
}
/**
* 饿汉式(静态代码块)
* 缺点,在类加载时就会被调用,可能造成内存的浪费
*/
class SingleTon02 {
// 1. 构造器私有化 外部不能new
private SingleTon02() {
}
// 2.在静态代码块中,穿件单例对象
private static SingleTon02 instance;
static {
instance = new SingleTon02();
}
// 3.提供一个共有的静态方法,返回实例对象
public static SingleTon02 getInstance() {
return instance;
}
}
/**
* 懒汉式(线程不安全写法,不要使用)
* 缺点,在多线程中,存在线程不安全的风险
*/
class SingleTon03 {
// 1. 构造器私有化 外部不能new
private SingleTon03() {
}
private static SingleTon03 instance;
// 2.提供一个共有的静态方法,返回实例对象
public static SingleTon03 getInstance() {
if (instance == null) {
instance = new SingleTon03();
}
return instance;
}
}
/**
* 懒汉式(线程安全写法,不推荐使用)
* 缺点,效率太低,多次调用getInstance时由于加了同步锁,所以效率低
*/
class SingleTon04 {
// 1. 构造器私有化 外部不能new
private SingleTon04() {
}
private static SingleTon04 instance;
// 2.提供一个共有的静态方法,返回实例对象
public static synchronized SingleTon04 getInstance() {
if (instance == null) {
instance = new SingleTon04();
}
return instance;
}
}
/**
* 懒汉式 (双重检查 线程安全的,效率也高 推荐使用)
*/
class SingleTon06 {
// 1. 构造器私有化 外部不能new
private SingleTon06() {
}
// volatile 表示,instance这个变量如果有修改立马会被更新到主存中去。
private static volatile SingleTon06 instance;
// 2.提供一个共有的静态方法,返回实例对象
public static SingleTon06 getInstance() {
if (instance == null) {
synchronized (SingleTon06.class) {
if (instance == null) {
instance = new SingleTon06();
}
}
}
return instance;
}
}
/**
* 静态内部类(★推荐使用,线程安全的,效率也高)
*/
class SingleTon07 {
// 1. 构造器私有化 外部不能new
private SingleTon07() {
}
// 2. 写一个静态内部类,该类中有一个静态属性instance
// 这个静态内部类,在SingleTon07加载时不会立马加载,所以时懒加载
// jvm在加载类的时候时线程安全的
private static class SingleTonInstance {
private static final SingleTon07 instance = new SingleTon07();
}
// 2.提供一个共有的静态方法,返回实例对象
public static SingleTon07 getInstance() {
return SingleTonInstance.instance;
}
}
/**
* 枚举的方式(★推荐使用)
*/
enum SingleTon08{
INSTANCE; // 属性
public void sayOk() {
System.out.println("maruis------>" + "ok!!!!!!!!!!");
}
}