首页 > 解决方案 > 状态模式:基于多个字段以及它们的值和状态值之间的一致性来更改对象行为

问题描述

我正在尝试了解状态模式。

在我见过的大多数状态模式示例中,类的方法仅基于一个字段来改变它们的行为(我的意思是应用状态模式之前,我不是在谈论状态接口类型的引用字段)并且该字段具有该类中没有其他用途,并且在应用状态模式后,他们将其删除。

但在我的课堂上,我有 2 个字段 (xy) 基于它们的值,该print()方法会改变其行为。而且我在一些业务逻辑方法中同时使用了这两个字段。

这是我的FunClass

public class FunClass {
    private int x;
    private int y;

    public MyClass(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void print() {
        if (x == 1 && y == 1) {
            System.out.println("XY");
        } else if (x == 1 && y == 0) {
            System.out.println("X");
        } else if (x == 0 && y == 1) {
            System.out.println("Y");
        } else if (x == 0 && y == 0) {
            System.out.println("nothing");
        }
    }
    
    // implement some business logic.
    public int sum() {
        return x + y;
    }

    //Setters And Getters ...
}

print()方法的行为基于对象的内部状态(内部状态,我的意思是字段 x 和 y)而有所不同。

所以我为这个方法应用了这个类的状态模式:

public class FunClass {

    private int x;
    private int y;

    private State xyState;

    public FunClass(int x, int y) {
        this.x = x;
        this.y = y;

        if (x == 1 && y == 1) {
            xyState = new XY();
        } else if (x == 1 && y == 0) {
            xyState = new X();
        } else if (x == 0 && y == 1) {
            xyState = new Y();
        } else if (x == 0 && y == 0) {
            xyState = new Nothing();
        }
    }

    public void print() {
        xyState.handlePrint(); //delegate to xyState to handle the request.
    }

    // implement some business logic.
    public int sum() {
        return x + y;
    }

    public void setX(int x) {
        this.x = x;

        if (x == 1 && this.y == 1) {
            xyState = new XY();
        } else if (x == 1 && this.y == 0) {
            xyState = new X();
        } else if (x == 0 && this.y == 1) {
            xyState = new Y();
        } else if (x == 0 && this.y == 0) {
            xyState = new Nothing();
        }
    }

    public void setY(int y) {
        this.y = y;

        if (this.x == 1 && y == 1) {
            xyState = new XY();
        } else if (this.x == 1 && y == 0) {
            xyState = new X();
        } else if (this.x == 0 && y == 1) {
            xyState = new Y();
        } else if (this.x == 0 && y == 0) {
            xyState = new Nothing();
        }
    }

    //Setters And Getters ...
}

我声明了State接口,并且在FunClass(即Context)中,我添加了一个状态接口类型的引用字段和一个允许覆盖该字段值的公共设置器。然后我添加了 4 个实现了 State 接口的类( X, Y, XY, )。Nothing

但是看看我的构造函数和我的设置器。我希望根据xy值选择状态实现(state字段的值和其他一些字段(xy)是相关的,并且它们的值之间必须有一致性。)我必须添加那些 if-else 语句。看起来我又回到了同样的问题。更糟!

有了这些条件,现在应该怎么办?这是否是滥用状态模式的一个例子?我们可以同时应用状态模式并摆脱条件吗?

PS:我的问题不是减少代码数量或只有一个实例的单一方法类,我的主要问题是状态模式。问题是我们应用了状态模式,但我们遇到了这样的情况。这些是我的问题:

  1. 这是否是滥用状态模式的一个例子?
  2. 我们可以同时应用状态模式并摆脱这些条件语句吗?

标签: oopdesign-patternsstate-pattern

解决方案


只需添加一个方法updateState

private void updateState() {
    if (x == 1 && y == 1) {
        xyState = new XY();
    } else if (x == 1 && y == 0) {
        xyState = new X();
    } else if (x == 0 && y == 1) {
        xyState = new Y();
    } else if (x == 0 && y == 0) {
        xyState = new Nothing();
    }
}

然后你的构造函数和设置器要简单得多:

public FunClass(int x, int y) {
    this.x = x;
    this.y = y;
    updateState();
}

public void setX(int x) {
    this.x = x;
    updateState();
}

public void setY(int y) {
    this.y = y;
    updateState();
}

不要放置 setXYState 方法:状态取决于 和 的xy


推荐阅读