更新ing
缩写 | 英文 | 中文 | 描述 |
---|---|---|---|
SRP | The Single Responsibility Principle | 单一责任原则 | 让一个类只做一种类型责任,当这个类需要承当其他类型的责任的时候,就需要分解这个类。 |
OCP | The Open Closed Principle | 开放封闭原则 | 软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。 |
LSP | The Liskov Substitution Principle | 里氏替换原则 | 当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系 |
DIP | The Dependency Inversion Principle | 依赖倒置原则 | 高层模块不应该依赖于低层模块,二者都应该依赖于抽象 2. 抽象不应该依赖于细节,细节应该依赖于抽象 |
ISP | The Interface Segregation Principle | 接口分离原则 | 不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好 |
定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
扩展:可以创建固定数量的对象。
本质
控制实例数目
优点
缺点
示例
懒汉式:时间换空间
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
饿汉式:空间换时间
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance(){
return instance;
}
}
最佳方案
public enum Singleton {
instance;
public void operation() {
// 操作
}
}
实际应用场景
定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
本质
选择产品簇的实现
优点
缺点
示例
抽象工厂接口
public interface AbstractFactory {
public AbstractProductA createProductA();
public AbstractProductB createProductB();
}
抽象产品A的接口
public interface AbstractProductA {
}
抽象产品B的接口
public interface AbstractProductB {
}
产品A具体实现
public class ProductA1 implements AbstractProductA {
}
public class ProductA2 implements AbstractProductA {
}
产品B具体实现
public class ProductB1 implements AbstractProductB {
}
public class ProductB2 implements AbstractProductB {
}
具体工厂实现
public class ConcreteFactory1 implements AbstractFactory {
public AbstractProductA createProductA() {
return new ProductA1();
}
public AbstractProductB createProductB() {
return new ProductB1();
}
}
public class ConcreteFactory2 implements AbstractFactory {
public AbstractProductA createProductA() {
return new ProductA2();
}
public AbstractProductB createProductB() {
return new ProductB2();
}
}
客户端
public class Client {
public static void main(String[] args) {
AbstractFactory af = new ConcreteFactory1();
af.createProductA();
af.createProductB();
}
}
实际应用场景
DAO(Data Access Object)数据访问对象
DAO抽象和封装所有对数据的访问。
定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使用一个类的实例化延迟到其子类。
本质
延迟到子类来选择实现
优点
缺点
示例
Product
public interface Product {
// 定义Product的属性和方法
}
ConcreteProduct
public class ConcreteProduct implements Product {
// 实现Product要求的方法
}
创建器
public abstract class Creator {
// 创建Product的工厂方法,一般不对外
protected abstract Product factoryMethod();
// 提供给外部使用的方法
public void someOperation() {
Product product = factoryMethod();
}
}
创建器具体实现
public class ConcreteCreator extends Creator {
protected Product factoryMethod() {
return new ConcreteProduct();
}
}
实际应用场景
IoC/DI
Q&A
定义
提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口,抽象类也可以是具体类。
本质
选择实现
优点
缺点
示例
API定义
/**
* 接口定义
* /
public interface Api {
public void operation(String s);
}
实现A
/**
* 接口的具体实现A
* /
public class ImplA implements Api {
public void operation(String s) {
System.out.println("ImplA s==" + s);
}
}
实现B
/**
* 接口的具体实现B
* /
public class ImplB implements Api {
public void operation(String s) {
System.out.println("ImplB s==" + s);
}
}
工厂类
public class Factory {
public static Api createApi(int condition) {
Api api = null;
if(condition == 1) {
api = new ImplA();
} else if(condition == 2) {
api = new ImplB();
}
return api;
}
}
配置版工厂类(反射,可考虑用NIO优化)
public class FactoryTest {
public static Api createApi() {
Properties p = new Properties();
InputStream in = null;
try {
in = FactoryTest.class.getResourceAsStream("FactoryTest.properties");
p.load(in);
} catch (IOException e) {
System.out.println("");
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Api api = null;
try {
api = (Api) Class.forName(p.getProperty("implClass")).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return api;
}
}
客户端
public class Client {
public static void main(String [] args) {
Api api = Factory.createApi(1);
api.operation("正在使用简单工厂");
}
}
配置版客户端
public class Client {
public static void main(String [] args) {
Api api = Factory.createApi();
api.operation("正在使用简单工厂");
}
}
实际应用场景
定义
将一个复杂的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
本质
分离整体构建算法和部件构造
优点
缺点
未总结
示例
生成器接口
public interface Builder {
public void buildPart();
}
具体生成器的实现
public class ConcreteBuilder implements Builder {
// 生成器最终构建的产品对象
private Product resultProduct;
// 获取最终构建的产品对象
public Product getResult() {
}s
public void buildPart() {
// 构建某个部件
}
}
相应的产品对象接口
public interface Product {
}
指导者
public class Director {
// 持有当前需要使用的生成器对象
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
// 指导生成器构建最终的产品对象
public void construct() {
// 通过使用生成器接口来构建最终的产品对象
builder.buildPart();
}
}
实际应用场景
定义
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象
本质
优点
缺点
示例
原型接口
public interface Prototype {
public Prototype clone();
}
克隆具体实现
public class ConcretePrototype1 implements Prototype {
private String field1;
private Product product1;
public String getProduct1() {
return this.product1;
}
pubilc void setProduct1(String product1) {
this.product1 = product1;
}
public String getField1() {
return this.field1;
}
pubilc void setField1(String field1) {
this.field1 = field1;
}
public Prototype clone() {
Prototype prototype = new ConcretePrototype1();
prototype.setField1(this.field1);
prototype.setProduct1((Product) this.product1.cloneProduct());
return prototype;
}
}
public class ConcretePrototype2 implements Prototype {
private String field2;
private Product product2;
public String getProduct2() {
return this.product2;
}
pubilc void setProduct2(String product2) {
this.product2 = product2;
}
public String getField2() {
return this.field2;
}
pubilc void setField2(String field2) {
this.field2 = field2;
}
public Prototype clone() {
Prototype prototype = new ConcretePrototype2();
prototype.setField1(this.field2);
prototype.setProduct2((Product) this.product2.cloneProduct());
return prototype;
}
}
原型管理器
public class PrototypeManager {
private static Map map = new HashMap();
private PrototypeManager() {
}
public synchronized static void setPrototype(String prototypeId, Prototype prototype) {
map.put(prototypeId, prototype);
}
public synchronized static void removePrototype(String prototypeId) {
map.remove(prototypeId);
}
public synchronized static Prototype getPrototype(String prototypeId) throws Exception {
Prototype prototype = map.get(prototypeId);
if(prototype == null) {
throw new Exception("您希望获取的原型还没有注册或已被销毁");
}
return prototype;
}
}
客户端
public class Client {
private Prototype prototype;
public Client(Prototype prototype) {
this.prototype = prototype;
}
public void operation() {
Prototype newPrototype = prototype.clone();
}
}
实际应用场景
定义
对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都得到通知并被自动更新。
本质
触发联动
优点
缺点
示例
目标对象
public class Subject {
private List observers = new ArrayList();
// 注册观察者对象
public void attach(Observer observer) {
observers.add(observer);
}
// 删除观察者对象
public void detach(Observer observer) {
observers.remove(observer);
}
// 通知所有注册的观察者对象
protected void notifyObservers() {
for(Observer observer: observers) {
observer.update(this);
}
}
}
具体的目标对象
public class ConcreteSubject extends Subject {
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String sunjectState) {
this.subjectState = subjectState;
this.notifyObservers();
}
}
观察者接口
public interface Observer {
public void update(Subject subject);
}
具体观察者
public class ConcreteObserver implements Observer {
private String observerState;
public void update(Subject subject) {
observerState = ((ConcreteSubject) subject).getSubjectState();
}
}
客户端
public class Client {
public static void main(String[] args) {
NewsPaper subject = new NewsPaper();
Reader reader1 = new Reader();
reader1.setName("张三");
Reader reader2 = new Reader();
reader2.setName("李四");
Reader reader3 = new Reader();
reader3.setName("李四");
subject.attach(reader1);
subject.attach(reader2);
subject.attach(reader3);
subject.setContent("本期内容是观察者模式");
}
}
实际应用场景
定义
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
本质
分离算法,选择实现
优点
缺点
示例
策略接口
public interface Strategy {
public void algorithmInterface();
}
具体策略
public interface ConcreteStrategyA implements Strategy {
public void algorithmInterface() {
}
}
public interface ConcreteStrategyB implements Strategy {
public void algorithmInterface() {
}
}
上下文
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void contextInterface() {
strategy.algorithmInterface();
}
}
实际应用场景
定义
使用多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到一个对象处理它为止。
本质
分离职责,动态组合
优点
缺点
示例
职责的接口
public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest();
}
通用的请求对象
public class RequestModel {
private String type;
public RequestModel(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
具体的请求对象
public class ConcreteRequestModel extends RequestModel {
public final static String A_TYPE = "A";
public ConcreteRequestModel() {
super(A_TYPE);
}
private String field1;
...
}
具体的职责对象
public class ConcreteHandler1 extends Handler {
public Object handleRequest(RequestModel rm) {
// 根据某些条件判断是否属于自己处理的职责范围
boolean someCondition = false;
Object result;
if(someCondition) {
// 处理
return result;
} else {
// 不处理,转发请求给后继职责对象
if(this.successor != null) {
return this.successor.handleRequest(rm);
} else {
return result;
}
}
}
}
客户端(可采用链表改进客户端)
public class Client {
public static void main(String[] args) {
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
h1.setSuccessor(h2);
h1.handleRequest();
}
}
实际应用场景
定义
本质
封装隔离
优点
缺点
示例
同事类的抽象父类
public abstract class Colleague {
private Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public Mediator getMediator() {
return mediator;
}
}
同事类A
public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
public void someOperation() {
// 需要跟其他同事通信的时候,通知中介者对象
getMediator().changed(this);
}
}
同事类B
public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
public void someOperation() {
// 需要跟其他同事通信的时候,通知中介者对象
getMediator().changed(this);
}
}
中介者接口
public interface Mediator {
public void changed(Colleague colleague);
}
中介者实现
public class ConcreateMediator implements Mediator {
private ConcreteColleagueA colleagueA;
private ConcreteColleagueB colleagueB;
public void setConcreteColleagueA(ConcreteColleagueA colleague) {
colleagueA = colleague;
}
public void setConcreteColleagueB(ConcreteColleagueB colleague) {
colleagueB = colleague;
}
public void changed(Colleague colleague) {
// 某个同事类发生了变化,通常需要与其他同事交互
// 具体协调相应的同事对象来实现协作行为
}
}
客户端
public class Client {
}
实际应用场景
定义
为子系统中的一组接口提供一个一致的界面,也就是一个高层接口。
本质
为多模块提供统一接口,封装交互,简化调用
优点
缺点
示例
A模块Api
public interface AModuleApi {
public void testA1(); //系统外部使用
public void testA2(); //系统内部使用
public void testA3(); //系统内部使用
}
实现A模块
public class AModuleImpl implements AModuleApi {
public void testA1() {
System.out.println("现在在A模块里面操作testA1方法");
}
public void testA2() {
System.out.println("现在在A模块里面操作testA2方法");
}
public void testA3() {
System.out.println("现在在A模块里面操作testA3方法");
}
}
B模块Api
public interface BModuleApi {
public void testB1(); //系统外部使用
public void testB2(); //系统内部使用
public void testB3(); //系统内部使用
}
实现B模块
public class BModuleImpl implements BModuleApi {
public void testB1() {
System.out.println("现在在B模块里面操作testB1方法");
}
public void testB2() {
System.out.println("现在在B模块里面操作testB2方法");
}
public void testB3() {
System.out.println("现在在B模块里面操作testB3方法");
}
}
C模块Api
public interface CModuleApi {
public void testC1(); //系统外部使用
public void testC2(); //系统内部使用
public void testC3(); //系统内部使用
}
实现B模块
public class CModuleImpl implements CModuleApi {
public void testC1() {
System.out.println("现在在C模块里面操作testC1方法");
}
public void testC2() {
System.out.println("现在在C模块里面操作testC2方法");
}
public void testC3() {
System.out.println("现在在C模块里面操作testC3方法");
}
}
外观接口
public interface FacadeApi {
// 只暴露对外部调用的接口
public void testA1();
public void testB1();
public void testC1();
public void test();
}
外观类
public class Facade {
public void test() {
AModuleApi a = new AModuleImpl();
a.testA1();
BModuleApi b = new BModuleApi();
b.testB1();
CModuleApi c = new CModuleImpl();
c.testC1();
}
}
客户端
public class Client {
public static void main(String [] args) {
Facade facade = new Facade();
facade.test();
}
}
实际应用场景
定义
为其他对象提供一种代理以控制对这个对象的访问。
本质
控制对象访问
优点
缺点
示例
抽象的目标接口
public interface Subject {
public void request();
}
具体的目标对象,是真正被代理的对象
public class RealSubject implements Subject {
public void request() {
}
}
代理对象的实现示意
public class Proxy implements Subject {
private RealSubject realSubject = null;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
public void request() {
// 在转调具体的目标对象前,可以执行一些功能处理
// 转调具体的目标对象的方法
realSubject.requst();
// 在转调具体的目标对象后,可以执行一些功能处理
}
}
实际应用场景
定义用户数据对象
public interface UserModelApi {
public String getUserId();
public void setUserId(String userId);
public String getName();
public void setName(String name);
public String getDepId();
public void setDepId(String depId);
public void String getSex();
public void setSex(String sex);
}
代理类
public class Proxy implements UserModelApi {
private UserModel realSubject = null;
public Proxy(UserModel realSubject){
this.realSubject = realSubject;
}
// 标识是否已经重新装载过数据
private boolean loaded = false;
public String getUserId() {
return realSubject.getUserId();
}
public void setUserId(String userId) {
realSubject.setUserId(userId);
}
public String getName() {
return realSubject.getName();
}
public void setName(String name) {
realSubject.setName(name);
}
public void setDepId(String depId) {
realSubject.setDepId(depId);
}
public void setSex(String sex) {
realSubject.setSex(sex);
}
public String getDepId() {
// 需要判读是否已经装载过了
if(!this.loaded) {
reload();
// 设置重新装载的标志为true
this.loaded = true;
}
return realSubject.getDepId();
}
public String getSex() {
// 需要判读是否已经装载过了
if(!this.loaded) {
reload();
// 设置重新装载的标志为true
this.loaded = true;
}
return realSubject.getSex();
}
private void reload() {
Connection conn = null;
try {
conn = this.getConnection();
String sql = "select * from tbl_user where userId = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, realSubject.getUserId());
if(re.next()) {
realSubject.setDepId(rs.getString("depId"));
realSubject.setSex(rs.getString("sex"));
}
rs.close();
pstmt.close();
} catch (Exception err) {
err.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
代理分类
定义
把不兼容的接口转换匹配成客户需要的接口,复用已有的功能
本质
转换匹配,复用功能。
优点
缺点
示例
Target Api
public interface Target {
public void request();
}
被适配的类
public class Adaptee {
public void specificRequest() {
//具体功能
}
}
适配器
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
}
}
客户端
public class Client {
public static void main(String [] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request();
}
}
实际应用场景
定义
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更为灵活。
本质
动态组合
优点
缺点
示例
组件对象的接口
public abstract class Component {
public abstract void operation();
}
具体实现组件对象
public class ConcreteComponent extends Component {
public void operation() {
}
}
装饰器的抽象父类
public abstract class Decorator extends Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
// 转发请求给组件对象,可以在转发前后执行一些附加动作
component.operation();
}
}
装饰器的具体实现A
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
// 添加的状态
private String addedState;
public String getAddedState() {
return addedState;
}
public void setAddedState(String addedState) {
this.addedState = addedState;
}
public void operation() {
// 调用父类的方法,可以在调用前后执行一些附加动作
super.operation();
// ...
String useAddedState = addedState;
}
}
装饰器的具体实现B
public class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
// 添加的职责
private void addedBehavior() {
// 需要添加的职责实现
}
public void operation() {
// 调用父类的方法,可以在调用前后执行一些附加动作
super.operation();
// ...
addedBehavior();
}
}
实际应用场景