上篇文章说了,适配器模式将某个接口转换成客户端期待的样子,装饰者模式是动态的将新功能附加到对象上,代理模式分为静态代理,动态jdk代理,cglib代理,优点是性能比jdk的高,但是创建对象耗时,所以单例模式适合cglib,反之适合jdk,并且因为动态传递对象,所以不适合final代理。外观模式整合子类提供唯一外观类给客服端。桥接模式将对象和属性抽离出来可以额外扩展,组合模式和享元模式等。
父类与子类:策略模式、模板方法模式、
两个类之间:观察者模式、迭代子模式、责任链模式、命令模式、
类的状态:备忘录模式、状态模式、
通过中间类:访问者模式、中介者模式、解释器模式
策略模式
定义:定义了一系列算法,并把每个算法封装,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。
解决的主要问题,使用ifelse维护起来复杂且代码修改量大。
优点就是算法自由切换,扩展性好,避免大量ifelse。
缺点就是策略类增多,代码量不少。
public interface Strategy {
public int calc(int a, int b);
}
public class Main1012 {
public static void main(String[] args) {
Environment1012 environment1012 = new Environment1012(new AddStrategy());
System.out.println(environment1012.calculate(1,2));
}
}
public class Environment1012 {
private Strategy strategy;
Environment1012(Strategy strategy){
this.strategy = strategy;
}
public int calculate(int a,int b){
return strategy.calc(a,b);
}
}
public class DeductionStrategy implements Strategy{
@Override
public int calc(int a, int b) {
return a - b;
}
}
public class AddStrategy implements Strategy{
@Override
public int calc(int a, int b) {
return a + b;
}
}
模板模式
定义:操作中算法的骨架,将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构即可重新定义算法某些特定步骤。
将一些步骤定义一个抽象方法,然后根据不同的业务场景来实现这个方法。
public static void main(String[] args) {
Dish cowAndTomato = new CowAndTomato();
cowAndTomato.doDish();
}
public class EggAndTomato extends Dish{
@Override
public void preparation() {
System.out.println("准备鸡蛋和番茄");
}
@Override
public void doing() {
System.out.println("炒西红柿鸡蛋");
}
@Override
public void client() {
System.out.println("西红柿鸡蛋给客户端吃");
}
}
public abstract class Dish {
void doDish(){
this.preparation();
this.doing();
this.client();
}
public abstract void preparation();
public abstract void doing();
public abstract void client();
}
public class CowAndTomato extends Dish{
@Override
public void preparation() {
System.out.println("准备牛肉和番茄");
}
@Override
public void doing() {
System.out.println("炒番茄炖牛腩");
}
@Override
public void client() {
System.out.println("给客户端吃");
}
}
优点:复合开闭原则,增加了扩展性,提高了代码复用,通过子类来增加扩展。
缺点:每个不同的业务都需要一个新的子类,类的个数增多。
观察者模式
定义:对象间的一种一对多依赖关系,当一个对象状态发生改变时,所有依赖它的对象都可以通知并且自动更新。
解决一个对象状态改变给其他对象通知的问题,而且要考虑到易用和耦合,保证高度的协作。
public static void main(String[] args) {
WechatServer wechatServer = new WechatServer();
Observer userZhang = new User("zhangsan");
Observer userLi = new User("lisi");
wechatServer.registerObserver(userZhang);
wechatServer.registerObserver(userLi);
wechatServer.setMsg("msg one one");
wechatServer.removeObserver(userLi);
wechatServer.setMsg("msg update ");
}
public interface Observer {
public void update(String msg);
}
public interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
public class User implements Observer {
private String name;
private String msg;
User(String name) {
this.name = name;
}
@Override
public void update(String msg) {
this.msg = msg;
read();
}
private void read() {
System.out.println(this.name + "msg:" + this.msg);
}
}
public class WechatServer implements Subject{
private List<Observer> observerList;
private String msg;
public WechatServer(){
observerList = Lists.newArrayList();
}
@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if(!CollectionUtils.isEmpty(observerList)){
observerList.remove(observer);
}
}
@Override
public void notifyObserver() {
for (Observer o: observerList) {
o.update(this.msg);
}
}
public void setMsg(String msg){
this.msg = msg;
notifyObserver();
}
}
迭代器模式
定义:提供一种方法顺序访问一个聚合对象中各个元素,而又无须暴露该对象内部表示。
解决的问题是不同的方式遍历整个整合对象。
优点:
1、他支持不同的方式遍历聚合对象。2、迭代器简化了聚合类。3、在同一个聚合上可以多个遍历。4、迭代器模式中,增加新的聚合类和迭代器类都很方便,复合开闭原则。
缺点:类的数量增加,当有新的聚合类就有新的迭代器,增加了系统复杂度。
责任链模式
定义:如果有多个对象有机会处理请求,责任链可使请求者和接收者解耦,请求一直沿着责任链传递,直到有对象处理他为止。
解决问题,责任链上的处理者负责处理请求,客户只需要将请求发送到职责链上,无须关系处理的细节,所以职责将请求的发送者和处理者解耦。利用拦截的类都实现统一接口来解决。
命令模式
定义:将一个请求封装为对象,使发出的请求和责任和执行请求责任分割开,这样两者之间通过命令对象进行沟通,这样方便将命令对象进行存储,传递,调用,增加与管理。
解决了在软件中,行为请求者和行为通常是紧耦合,但某些情况,需要对行为进行记录,撤销或重做,事务等处理,这种紧耦合就不太合适。
状态模式
定义:我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的context对象。
解决了对象的行为依赖于它的状态,并且可以通过他的状态来改变相关行为。
通常命令模式的接口只有一个方法,而状态模式接口有一个或者多个方法,状态和命令一样,可以消除ifelse等语句。
备忘录模式
定义:在不破坏封装线前提下,捕获一个对象内部状态,并在该对象之外保存这个状态,以便恢复到原先保存的状态。又叫快照模式。
提供了恢复机制,方便数据恢复到某个历史时刻。
访问者模式
定义:将作用于某种数据结构中各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素新的操作,为数据结构中每个元素提供多种访问方式,对数据操作和数据结构进行分离。
把访问者和相关行为封装在一起,复合单一职责原则。
中介者模式
定义:定义一个中介对象来封装与对象之间的交互,使对象间耦合度降低,独立的互相交互,迪米特法则的典型应用。
对象之间一一对象,易于高复用,更灵活维护和扩展。