为什么要使用设计模式
合理的使用设计模式,可以提高系统的健壮性,易修改性和可扩展性
六大设计原则
- 单一原则 :类或方法应该只有有单一的职责
- 里氏替换原则 :任何能使用基类的地方,都应该可以使用其子实现替换
- 开闭原则 :对扩展开放,对修改禁止
- 依赖倒置 :应该依赖接口而不是依赖具体实现,即面向接口编程,应该对外暴露接口
- 接口隔离原则 :每个接口应该有自己独立的功能,不要在一个接口中定义多个功能。类要实现多个功能需要实现不同功能的接口。对外暴露接口的时候,也要做到最小化接口
- 迪米特法则 :也叫最小知道法则,即要尽量避免与其他类的交流,应该只与内部变量,方法输入与输出中的类交流
创建型(五种):
==简单工厂模式(不属于23中设计模式)==:
根据不同的入参创建不同的对象undefined 每次增加新的对象都需要修改代码
spring中的BeanFactory就是用的简单工厂模式, 通过传入的唯一标识,返回需要的bean实例
==工厂模式==:
为每一个产品创建一个工厂类,通过不同的工厂实例来创建不同的产品undefined 方便增加同一等级的不同产品
spring中的FactoryBean接口采用了工厂方法模式,当注入相关bean时,Spring会先获取FactoryBean的实例,再调用用户实现的getObject方法返回对应的bean
==抽象工厂模式==:
为每一产品类创建一个工厂类,通过不同的工厂类来创建一类产品undefined 方便扩展产品类,但不方便在产品类中添加新的产品
简单工厂模式、工厂方法模式、抽象工厂模式,是一个由简到繁,根据需求的不断复杂化多样化而诞生的过程,工厂模式其实就是根据工厂创建对象,只不过有的是小作坊,有的是大车间
Demo:
// 定义产品
public interface Phone {}
public interface PC {}
public class MiPhone implements Phone {}
public class MiPC implements PC {}
public class IPhone implements Phone{}
public class Mac implements PC {}
简单工厂
public class SimpleFactory {
public static <T extends Phone> T makePhone(String type) {
if ("mi".equals(type)) {
return (T) new MiPhone();
} else if ("apple".equals(type)) {
return (T) new IPhone();
} else {
return null;
}
}
}
public class Client {
public static void main(String[] args) {
MiPhone miPhone = SimpleFactory.makePhone("mi");
}
}
工厂模式
public interface AbstractFactory {
Phone makePhone();
}
public class MiFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new MiPhone();
}
}
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
}
public class Client {
public static void main(String[] args) {
AbstractFactory miFactory = new MiFactory();
AbstractFactory appleFactory = new AppleFactory();
MiPhone miPhone = (MiPhone) miFactory.makePhone();
IPhone iPhone = (IPhone) appleFactory.makePhone();
}
}
抽象工厂模式
public interface AbstractFactory {
Phone makePhone();
PC makePC();
}
public class MiFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new MiPhone();
}
@Override
public PC makePC() {
return new MiPC();
}
}
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
@Override
public PC makePC() {
return new Mac();
}
}
public class Client {
public static void main(String[] args) {
AbstractFactory miFactory = new MiFactory();
AbstractFactory appleFactory = new AppleFactory();
miFactory.makePhone();
miFactory.makePC();
appleFactory.makePhone();
appleFactory.makePC();
}
}
==单例模式==:
保证全局仅有一个对象实例,并提供一个对外的实例访问点undefined 违背了单一职责原则
单例的几种实现方式:
- 饿汉式 :
优点:线程安全undefined 缺点:不用的话,实力也会创建,浪费资源,由于在启动时就会创建,会导致启动变慢
public class SingletonClass {
public static final SingletonClass INSTANCE = new SingletonClass();
private SingletonClass {}
}
- 懒汉式 :
优点:使用时才加载,节约系统资源undefined 缺点:处理线程安全问题麻烦
DCL1.0 该实现方式存在缺陷, JMM设计原因导致
public class SingletonClass {
private static SingletonClass instance = null;
private SingletonClass {}
public static SingletonClass getInstance() {
if (instance == null) {
synchronized (this) {
if (instance == null) {
instance = new SingletonClass();
}
}
}
return instance;
}
}
DLC2.0
public class SingletonClass {
private static volatile SingletonClass instance = null;
private SingletonClass {}
public static SingletonClass getInstance() {
if (instance == null) {
synchronized (this) {
if (instance == null) {
instance = new SingletonClass();
}
}
}
return instance;
}
}
- Holder模式
优点,兼具饿汉和懒汉模式优点,线程安全,不使用不会加载,节约资源
public class SingletonClass {
private static class SingletonClassHolder {
private static final SingletonClass INSTANCE = new SingletonClass();
}
private SingletonClass {}
public static SingletonClass getInstance() {
return SingletonClassHolder.INSTANCE;
}
}
==思考一下,上述的几种实现方式是否有办法破坏,tips:java反射,java序列化==
- 枚举模式
优点:安全,简单,无多线程问题undefined 缺点:见饿汉模式
public enum SingletonClass {
INSTANCE;
public void doSomthing() {
// TODO
}
}
原型模式:
用于创建重复的对象,同时还能保证性能。undefined 通过实现Cloneable接口的clone方法来实现原型模式。
public class PrototypeClass implements Cloneable {
@Override
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
创建者模式:
将一个复杂的对象构建与其表示分离,使得同样的构建过程可以创建不同的表示
MultipartBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("fileData", "a.pdf", fileBody)
.addFormDataPart("meta", "{\"thresh\":0.7}")
.addFormDataPart("token", pdfAddrToken)
.build();
Request request = new Request.Builder()
.header("Content-Type", "multipart/form-data")
.post(body)
.url(addRess)
.build();