3 minute read

行为型模式

关注类与类之间的交互与协作

1.责任链模式(Chain of responsibility)

每个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。处理职责相同,程度不同的类

国王向将军传递命令,将军向士兵传递命令。

public abstract class Client {
    protected Client next;

    public void setNext(Client next) {
        this.next = next;
    }

    abstract void handle(Request request);
}
public class PrimaryClient extends Client {

    @Override
    void handle(Request request) {
        if (request.value > 0 && request.value <= 10) {
            solve(request);
        } else if (next != null) {
            next.handle(request);
        }
    }

    private void solve(Request request) {
        System.out.println("初级客服解决了" + request.value);
    }
}
public class HighClient extends Client {
    @Override
    void handle(Request request) {
        if (request.value > 10) {
            solve(request);
        } else if (next != null) {
            next.handle(request);
        }
    }

    private void solve(Request request) {
        System.out.println("高级客服解决了" + request.value);
    }
}
public class Request {
    int value;

    public Request(int value) {
        this.value = value;
    }
}
public class Demo {
    public static void main(String[] args) {
        PrimaryClient primaryClient = new PrimaryClient();
        HighClient highClient = new HighClient();
        
        Request easy = new Request(10);
        Request hard = new Request(20);
        //组成责任链
        primaryClient.setNext(highClient);

        primaryClient.handle(easy);
        primaryClient.handle(hard);
    }
}

结果

初级客服解决了10
高级客服解决了20

可以看到客服之间形成了责任链,当初级客服解决不了的问题交给高级客服做

2.命令模式(Command)

将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化

public interface Order {
    void execute();
}
public class Stock {
    private String name = "ABC";
    private int quantity = 10;

    public void buy() {
        System.out.println(name + "buy:" + quantity);
    }

    public void sell() {
        System.out.println(name + "sell:" + quantity);
    }
}
public class BuyStock implements Order {

    private Stock stock;

    public BuyStock(Stock stock) {
        this.stock = stock;
    }

    @Override
    public void execute() {
        stock.buy();
    }
}
public class SellStock implements Order {

    private Stock stock;

    public SellStock(Stock stock) {
        this.stock = stock;
    }

    @Override
    public void execute() {
        stock.sell();
    }
}
public class Broker {
    private List<Order> orderList = new ArrayList<Order>();

    public void takeOrder(Order order) {
        orderList.add(order);
    }

    public void placeOrders() {
        for (Order order : orderList) {
            order.execute();
        }
        orderList.clear();
    }
}
public class Demo {
    public static void main(String[] args) {
        Stock abcStock = new Stock();

        BuyStock buyStockOrder = new BuyStock(abcStock);
        SellStock sellStockOrder = new SellStock(abcStock);

        Broker broker = new Broker();
        broker.takeOrder(buyStockOrder);
        broker.takeOrder(sellStockOrder);

        broker.placeOrders();
    }
}

3.解释器模式(Interpreter)

提供了评估语言的语法或表达式的方式。用于SQL解析,符号处理引擎

public abstract class Expression{
    public abstract int interpret();
    
    @Override
    public abstract String toString();
}
public class NumberExpression extends Expression{
    private final int number;

    public NumberExpression(int number) {
        this.number = number;
    }

    public NumberExpression(String s) {
        this.number = Integer.parseInt(s);
    } 
    
    @Override
    public int interpret() {
        return number;
    }

    @Override
    public String toString() {
        return "number";
    }
}
public class PlusExpression extends Expression{
    private final Expression leftExpression;
    private final Expression rightExpression;

    public PlusExpression(Expression leftExpression, Expression rightExpression) {
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    @Override
    public int interpret() {
        return leftExpression.interpret() + rightExpression.interpret();
    }

    @Override
    public String toString() {
        return "+";
    }
}

4.迭代器模式(Iterator)

提供一种方法访问一个容器对象中的各个元素,而又不需暴露该对象的内部细节

核心在于定义next()方法和hasNext()方法,让外部类使用这两个方法来遍历列表从而隐藏内部细节

Java本身也提供了for-each来访问。

public class Demo {
    public static void main(String[] args) {
        List<String> str = Arrays.asList("a", "b", "c");
        for (String s : str) {
            System.out.println(s);
        }
    }
}

5.中介者模式(Mediator)

定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立的改变它们之间的交互。

举例:聊天室。所有类把消息发给聊天室,然后在聊天室获取需要的信息。

定义一个partyMember

public interface PartyMember {

  void joinedParty(Party party);

  void partyAction(Action action);

  void act(Action action);
}
@Slf4j
public abstract class PartyMemberBase implements PartyMember {

  protected Party party;

  @Override
  public void joinedParty(Party party) {
    LOGGER.info("{} joins the party", this);
    this.party = party;
  }

  @Override
  public void partyAction(Action action) {
    LOGGER.info("{} {}", this, action.getDescription());
  }

  @Override
  public void act(Action action) {
    if (party != null) {
      LOGGER.info("{} {}", this, action);
      party.act(this, action);
    }
  }

  @Override
  public abstract String toString();
}
public class Rogue extends PartyMemberBase {

  @Override
  public String toString() {
    return "Rogue";
  }

}
public interface Party {

  void addMember(PartyMember member);

  void act(PartyMember actor, Action action);

}
public class PartyImpl implements Party {

  private final List<PartyMember> members;

  public PartyImpl() {
    members = new ArrayList<>();
  }

  @Override
  public void act(PartyMember actor, Action action) {
    for (var member : members) {
      if (!member.equals(actor)) {
        member.partyAction(action);
      }
    }
  }

  @Override
  public void addMember(PartyMember member) {
    members.add(member);
    member.joinedParty(this);
  }
}

6.备忘录模式(Memento)

类似游戏存档、读档。在保护破坏封装的条件下,通过备忘录对象存储另一个对象内部的快照,在将来合适的时候把这个对象还原到存储起来的状态。

7.观察者模式(Observer)

当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新

如天气变化的时候,动物会进行相应的反应。

public interface WeatherObserver {

  void update(WeatherType currentWeather);

}
@Slf4j
public class Hobbits implements WeatherObserver {

  @Override
  public void update(WeatherType currentWeather) {
    LOGGER.info("The hobbits are facing {} weather now", currentWeather.getDescription());
  }
}
@Slf4j
public class Weather {

  private WeatherType currentWeather;
  private final List<WeatherObserver> observers;

  public Weather() {
    observers = new ArrayList<>();
    currentWeather = WeatherType.SUNNY;
  }

  public void addObserver(WeatherObserver obs) {
    observers.add(obs);
  }

  public void removeObserver(WeatherObserver obs) {
    observers.remove(obs);
  }

  /**
   * Makes time pass for weather.
   */
  public void timePasses() {
    var enumValues = WeatherType.values();
    currentWeather = enumValues[(currentWeather.ordinal() + 1) % enumValues.length];
    LOGGER.info("The weather changed to {}.", currentWeather);
    notifyObservers();
  }

  private void notifyObservers() {
    for (var obs : observers) {
      obs.update(currentWeather);
    }
  }
}

8.状态模式(State)

类的行为是基于它的状态改变的

9.策略模式(Strategy)

一个类的行为或其算法可以在运行时更改。如排序有冒泡排序、选择排序、插入排序等等,定义一个排序接口,然后用不同类实现,排序的时候选择具体哪一种算法就是策略模式。

10.模板方法模式(Template-method)

一个抽象类公开定义了执行它的方法的模板

//模板
public abstract class LeaveRequest {
    void request() {
        System.out.println("本人因");
        System.out.println(reasone());
    }

    abstract String reasone();
}
public class MyLeave extends LeaveRequest {
    @Override
    String reasone() {
        return "你懂";
    }
}
public class Demo {
    public static void main(String[] args) {
        new MyLeave().request();
    }
}

11.访问者模式(Visitor)

对某对象结构中的各元素操作,使得可以在不改变各元素类的前提下定义作用于这些元素的新操作。核心思想是将数据的结构与对数据的操作分离