Шаблон состояния: Изменение поведения объекта на основе более чем одного поля и согласованности между их значениями и значением состояния.

#oop #design-patterns #state-pattern

Вопрос:

Я пытаюсь узнать о структуре штата.

В большинстве государственного образца примеры, которые я видел, методы класса, менять свое поведение на основе только одного поля (я имею в виду , прежде чем применять шаблон, и я говорю не о поле Ссылка государственного интерфейс типа), а также что поле обладает никакое другое использование в этом классе и после применения государственного образца, их удалить.

но в моем классе у меня есть 2 поля ( x и y ), которые в зависимости от их значений 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 amp;amp; y == 1) {
            System.out.println("XY");
        } else if (x == 1 amp;amp; y == 0) {
            System.out.println("X");
        } else if (x == 0 amp;amp; y == 1) {
            System.out.println("Y");
        } else if (x == 0 amp;amp; 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 amp;amp; y == 1) {
            xyState = new XY();
        } else if (x == 1 amp;amp; y == 0) {
            xyState = new X();
        } else if (x == 0 amp;amp; y == 1) {
            xyState = new Y();
        } else if (x == 0 amp;amp; 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 amp;amp; this.y == 1) {
            xyState = new XY();
        } else if (x == 1 amp;amp; this.y == 0) {
            xyState = new X();
        } else if (x == 0 amp;amp; this.y == 1) {
            xyState = new Y();
        } else if (x == 0 amp;amp; this.y == 0) {
            xyState = new Nothing();
        }
    }

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

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

    //Setters And Getters ...
}
 

Я объявил State интерфейс и в FunClass (который есть Context ) я добавил поле ссылки типа интерфейса состояния и общедоступный установщик, который позволяет переопределять значение этого поля. а затем я добавил 4 класса ( X , Y , XY , Nothing ), которые реализовали интерфейс состояния.

Но посмотрите на моего конструктора и моих сеттеров. Я хотел, чтобы реализация состояния выбиралась на основе x y значений и (значения state поля и некоторых других полей( x и y ) связаны, и между их значениями должна быть согласованность.) и мне пришлось добавить эти утверждения «если бы еще». И, похоже, я вернулся к той же проблеме. еще хуже!

Что теперь делать с этими условиями? Является ли это примером неправильного использования государственного образца или нет? Можем ли мы одновременно применить шаблон состояния и избавиться от условий?

PS: Моя проблема не в уменьшении количества кодов или наличии класса с одним методом только с одним экземпляром, и моя главная проблема-это шаблон состояния. проблема в том, что мы применили шаблон состояния, но у нас такая ситуация. и это мои вопросы:

  1. Является ли это примером неправильного использования государственного образца или нет?
  2. Можем ли мы одновременно применить шаблон состояния и избавиться от этих условных операторов?

Ответ №1:

Просто добавьте метод updateState :

 private void updateState() {
    if (x == 1 amp;amp; y == 1) {
        xyState = new XY();
    } else if (x == 1 amp;amp; y == 0) {
        xyState = new X();
    } else if (x == 0 amp;amp; y == 1) {
        xyState = new Y();
    } else if (x == 0 amp;amp; 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: состояние зависит от значений x и y .

Комментарии:

1. проблема не решается путем извлечения метода из повторяющихся условных операторов, и проблема по-прежнему остается той же, что и раньше.