美文网首页
设计模式回顾(四)

设计模式回顾(四)

作者: yuLiangC | 来源:发表于2021-09-29 23:29 被阅读0次

接前篇,行为型设计模式数量较多,之前没有讲完,还剩下备忘录模式、状态模式、策略模式和中介者模式,本章继续。

备忘录模式

备忘录模式用于保存对象的状态,当有需要时再恢复过来。例如对文档进行操作时操作错误,想要恢复到上一步正确的状态,那么就需要对上一次正确的操作状态进行保存。
通常应用于游戏状态保存,文档快照保存等。
具体设计到以下几个对象
-Originator:需要保存的对象。这个对象可能会很复杂或者内容繁多,如果每次都将它复制一份将会耗费大量内存,所以可以只保存它的状态即可。至于每种状态下对象应该如何管理和显示,则由originer自己来实现和负责。
-memo:备忘录对象。为什么要专门弄一个备忘录对象,因为状态可能有很多类型,所以一个基本类型不一定能囊括得了,比如斗地主的时候当前的游戏进度,玩家信息,手上牌的张数大小等等都不一样。备忘录对象由originer创建,它会保存几个originer的状态信息,当originer要恢复到以前的状态时就将自己的状态值传给originer.
-CareTaker:备忘录管理者。因备忘录对象不止一个,所以还需要一个管理者,它负责存储和清除备忘录。


image.png

代码如下:
Originator

public class Originator {

    private String state;
    private int step;

    public void setState(String state,int step) {
        this.state = state;
        this.step = step;
    }

    public void setStep(int step) {
        this.step = step;
    }

    public Memo saveMemo(){
        return new Memo(state,step);
    }

    public void restoreFormMemo(Memo memo){
        state = memo.getState();
        step = memo.getStep();
    }

    public String getState() {
        return state;
    }

    public int getStep() {
        return step;
    }


    @Override
    public String toString() {
        return "Originator{" +
                "state='" + state + '\'' +
                ", step=" + step +
                '}';
    }
}

Memo

public class Memo {

    private String state;
    private int step;

    public Memo(String state, int step) {
        this.state = state;
        this.step = step;
    }

    public String getState() {
        return state;
    }

    public int getStep() {
        return step;
    }
    
}

CareTaker

public class CareTaker {

    private List<Memo> memoList = new ArrayList<>();

    public void addMemo(Memo memo){
        memoList.add(memo);
    }

    public void removeMemo(Memo memo){
        memoList.remove(memo);
    }

    public Memo getMemo(int index){
        return memoList.get(index);
    }
    
}

测试代码

    public static void main(String[] args) {
        Originator originator = new Originator();
        originator.setState("state 1...",1);
        CareTaker taker = new CareTaker();
        taker.addMemo(originator.saveMemo());
        System.out.println("初始值:"+ originator);
        originator.setState("state 2...",2);
        originator.setState("state 3...",3);
        System.out.println("改变之后:"+ originator);
        taker.addMemo(originator.saveMemo());
        originator.restoreFormMemo(taker.getMemo(0));
        System.out.println("恢复到之前:"+ originator);
    }

状态模式

该模式和策略模式类似,都是为了避免在项目中使用过多的条件判断,多层的条件判断会让代码易读性变差且难以维护。如果在不通的状态下需要进行不同的行为操作,则可以使用状态模式。
该模式会把行为抽象成一个接口,每个具体行为会根据这个接口传入的state不同来进行自己的操作。
主要包含以下类:
-context:环境类,它保存了当前的状态接口类,提供一个改变当前状态的方法,其工作直接由状态类实现。
-action:接口;每一个具体的执行者都实现了该接口。
-具体的执行类。
例如,小明昨天上班路上扶老奶奶过马路,老奶奶强行给了他一百块钱作为报酬,于是小明开开心心的去上班,昨天的工作效率很高,一会儿就把事情做完了;而今天上班路上遇到另一位老奶奶碰瓷,让他赔偿几万块的医药费,小明就一直在愤懑社会为什么这么多坏人所以无心工作,今天上班啥也没干成。这就是在不同的状态下工作结果不一样。


image.png

具体代码如下:
State

public interface State {
    void doWork();
}

WorkHappy

public class WorkHappy implements State {

    @Override
    public void doWork() {
        System.out.println("WorkHappy ...");
    }
}

WorkSad

public class WorkSad implements State {

    @Override
    public void doWork() {
        System.out.println("WorkSad ...");
    }
    
}

Context

public class Context {

    private State state;

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public void changeState(State state){
        this.state = state;
    }

    public void doWork(){
        state.doWork();
    }

}

测试代码

   public static void main(String[] args) {
        Context context = new Context();
        context.setState(new WorkHappy());
        context.doWork();
        context.changeState(new WorkSad());
        context.doWork();
    }

策略模式

本模式和状态模式很相似,都是在面临复杂业务逻辑的时候为了避免陷入多种条件判断的地狱而产生的设计模式,不同的是,策略模式是对同一事情的不同策略实现,不注重时间策略切换,状态模式是在不同状态下做不同的事情,侧重状态的切换变化。
具体类如下:
-strategy:策略接口。对一件事情做法的抽象,可以有多个实现方法
-context:环境类。持有策略接口的引用,使用了某个策略的类。
例如:加减乘除分别代表了不同的算法,现在有两个数字a,b,假设对他们进行这四种运算都算是实现某种结果的四种策略,那么可以定义一个运算接口,然后分别实现四种策略算法。


image.png

代码如下:
Strategy

public interface Strategy {
    int operation(Num num);
}

Num

public class Num {
    private int a;
    private int b;

    public Num(int a, int b) {
        this.a = a;
        this.b = b;
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }
}

StrategyAdd

public class StrategyAdd implements Strategy {

    @Override
    public int operation(Num num) {
        return num.getA() + num.getB();
    }
}

Context

public class Context {

    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public int executeStrategy(Num num){
        return strategy.operation(num);
    }
}

其他集中算法实现就不贴了,一看了然。直接看测试代码:

 public static void main(String[] args) {
        Num num = new Num(300,20);
        Context addContext = new Context(new StrategyAdd());
        System.out.println("add num ="+addContext.executeStrategy(num));
        Context subContext = new Context(new StrategySub());
        System.out.println("sub num ="+subContext.executeStrategy(num));
        Context multiContext = new Context(new StrategyMulti());
        System.out.println("multi num ="+multiContext.executeStrategy(num));
        Context divContext = new Context(new StrategyDiv());
        System.out.println("div num ="+divContext.executeStrategy(num));
    }

中介者模式

当对象与对象之间的关系错综复杂时,容易造成管理混乱和出错,因此提供中介者。它会将各个不同的对象进行协调和调配,使之协同工作。
有了中介者之后,对象不在与各自对象进行沟通交互,而直接和中介者进行沟通,这样原来的网状关系结构变成了中心点放射式结构。
例如房屋中介将所有房源都收集起来,租户需要租房时直接找中介者就能避免很多琐碎的程序和风险问题,让专业的人做专业的事,恰好符合单一职责原则。
再比如用户和用户聊天需要聊天室,聊天室就类似于一个中介者,它会将每个用户的消息,姓名,发送时间展示给其他用户看。


image.png

代码如下:
User

public interface User {
    String getName();
    void sendMsg(String msg);
}

XiaoHong

public class XiaoHong implements User{
    @Override
    public String getName() {
        return "XiaoHong";
    }

    @Override
    public void sendMsg(String msg) {
        ChatRoom.sendMsg(this,msg);
    }
}

Xiaoming

public class Xiaoming implements User{
    @Override
    public String getName() {
        return "Xiaoming";
    }

    @Override
    public void sendMsg(String msg) {
        ChatRoom.sendMsg(this,msg);
    }
}

ChatRoom

public class ChatRoom {
    public static void sendMsg(User user,String msg){
        System.out.println(user.getName()+" say "+msg);
    }
}

测试代码

    public static void main(String[] args) {
        User xiaoMing = new XiaoHong();
        xiaoMing.sendMsg("how ary you?");
        User xiaoHong = new Xiaoming();
        xiaoHong.sendMsg("fine,think you.");
    }

相关文章

  • 设计模式回顾(四)

    接前篇,行为型设计模式数量较多,之前没有讲完,还剩下备忘录模式、状态模式、策略模式和中介者模式,本章继续。 备忘录...

  • 设计模式回顾

    Java总共有23种设计模式,平时经常用到的也就十几种,在此回顾一下,做下总结。我们从对象的三个特征来总结: 一,...

  • Java设计模式——原型模式

    Java设计模式之原型模式 回顾 Java设计模式系列的上一期写了工厂模式,那么创建类的设计模式还有生成器模式和原...

  • 前端设计模式

    JS设计模式一:工厂模式jS设计模式二:单例模式JS设计模式三:模块模式JS设计模式四:代理模式JS设计模式五:职...

  • Java设计模式——生成器模式

    Java设计模式之生成器模式 回顾 这期继续跟大家聊下创建型的设计模式,如果想了解其他创建类的设计模式有哪些,可以...

  • 第1章 设计模式概述

    一、设计模式的概念 二、设计模式的历史 三、设计模式的要素 四、设计模式的分类 ■ 创建型设计模式 ■ 结构型设计...

  • 领域驱动架构的演进

    我们回顾了经典三层架构与领域驱动设计四层架构,然后又对分层架构模式的产生与设计原则做了一次历史回顾。我们先后参考了...

  • Go单例模式

    单例模式回顾 以前在做java的时候,经常会用到设计模式,如单例模式、工厂模式、观察者模式等。其实设计模式和语言无...

  • 单例模式

    面向对象设计的设计模式(四):单例模式

  • 设计模式四、抽象工厂模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 抽象工厂模式 ...

网友评论

      本文标题:设计模式回顾(四)

      本文链接:https://www.haomeiwen.com/subject/ddnvbltx.html