#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:
Просто добавьте метод 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. проблема не решается путем извлечения метода из повторяющихся условных операторов, и проблема по-прежнему остается той же, что и раньше.