В одном месте заменяет switch. вместо наследования использует шаблон "Состояние":
"... Такой прием позволяет заменить оператор switch полиморфизмом. К сожалению, у этого решения есть маленький недостаток – оно не работает. Фильм за время своего существования может изменить тип,
объект же, пока он жив, изменить свой класс не может. Однако выход есть – паттерн «Состояние» (State pattern [Gang of Four])" стр52.
Может мне кто то объяснить, зачем?
Почему надо изменять свой класс?
public abstract class Movie
{
public abstract double GetCharge(int daysRented);
}
public class CHILDRENSMovie : Movie
{
public override double GetCharge(int daysRented)
{
throw new NotImplementedException();
}
}
public class REGULARMovie : Movie
{
public override double GetCharge(int daysRented)
{
throw new NotImplementedException();
}
}
Здравствуйте, zfima, Вы писали:
Z>Здравствуйте
Z>Осваиваю книгу Рефакторинг Мартина Фулера.
Z>В одном месте заменяет switch. вместо наследования использует шаблон "Состояние": Z>"... Такой прием позволяет заменить оператор switch полиморфизмом. К сожалению, у этого решения есть маленький недостаток – оно не работает. Фильм за время своего существования может изменить тип, Z>объект же, пока он жив, изменить свой класс не может. Однако выход есть – паттерн «Состояние» (State pattern [Gang of Four])" стр52.
Z>Почему надо изменять свой класс?
В твоем примере с Movie вполне может оказаться, что тип кина поменяется с Regular на Children, что твоя объектная модель не выдержит.
А вообще state нужен для моделирования объектов со встроенным поведением. Например монстры в игре вполне могут по разному вести себя в зависимости от уровня здоровья. Чтобы не делать россыпи if и switch в методах можно воспользоваться паттерном state.
Re[2]: Выбор шаблона "Состояние" вместо наследования
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, zfima, Вы писали:
Z>>Здравствуйте
Z>>Осваиваю книгу Рефакторинг Мартина Фулера.
Z>>В одном месте заменяет switch. вместо наследования использует шаблон "Состояние": Z>>"... Такой прием позволяет заменить оператор switch полиморфизмом. К сожалению, у этого решения есть маленький недостаток – оно не работает. Фильм за время своего существования может изменить тип, Z>>объект же, пока он жив, изменить свой класс не может. Однако выход есть – паттерн «Состояние» (State pattern [Gang of Four])" стр52.
Z>>Почему надо изменять свой класс?
G>В твоем примере с Movie вполне может оказаться, что тип кина поменяется с Regular на Children, что твоя объектная модель не выдержит.
G>А вообще state нужен для моделирования объектов со встроенным поведением. Например монстры в игре вполне могут по разному вести себя в зависимости от уровня здоровья. Чтобы не делать россыпи if и switch в методах можно воспользоваться паттерном state.
Спасибо за объяснение!
Re[2]: Выбор шаблона "Состояние" вместо наследования
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, zfima, Вы писали:
Z>>Здравствуйте
Z>>Осваиваю книгу Рефакторинг Мартина Фулера.
Z>>В одном месте заменяет switch. вместо наследования использует шаблон "Состояние": Z>>"... Такой прием позволяет заменить оператор switch полиморфизмом. К сожалению, у этого решения есть маленький недостаток – оно не работает. Фильм за время своего существования может изменить тип, Z>>объект же, пока он жив, изменить свой класс не может. Однако выход есть – паттерн «Состояние» (State pattern [Gang of Four])" стр52.
Z>>Почему надо изменять свой класс?
G>В твоем примере с Movie вполне может оказаться, что тип кина поменяется с Regular на Children, что твоя объектная модель не выдержит.
G>А вообще state нужен для моделирования объектов со встроенным поведением. Например монстры в игре вполне могут по разному вести себя в зависимости от уровня здоровья. Чтобы не делать россыпи if и switch в методах можно воспользоваться паттерном state.
После имплементации Состояния, сложилось впечатление, что шаблон состояние = Dependency Injection + делегирование поведения другому классу
Это так?
Re[3]: Выбор шаблона "Состояние" вместо наследования
Здравствуйте, zfima, Вы писали:
Z>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, zfima, Вы писали:
Z>>>Здравствуйте
Z>>>Осваиваю книгу Рефакторинг Мартина Фулера.
Z>>>В одном месте заменяет switch. вместо наследования использует шаблон "Состояние": Z>>>"... Такой прием позволяет заменить оператор switch полиморфизмом. К сожалению, у этого решения есть маленький недостаток – оно не работает. Фильм за время своего существования может изменить тип, Z>>>объект же, пока он жив, изменить свой класс не может. Однако выход есть – паттерн «Состояние» (State pattern [Gang of Four])" стр52.
Z>>>Почему надо изменять свой класс?
G>>В твоем примере с Movie вполне может оказаться, что тип кина поменяется с Regular на Children, что твоя объектная модель не выдержит.
G>>А вообще state нужен для моделирования объектов со встроенным поведением. Например монстры в игре вполне могут по разному вести себя в зависимости от уровня здоровья. Чтобы не делать россыпи if и switch в методах можно воспользоваться паттерном state.
Z>После имплементации Состояния, сложилось впечатление, что шаблон состояние = Dependency Injection + делегирование поведения другому классу Z>Это так?
Может и так, это уже вопрос терминологии.
Вообще паттерн state говорит о том, что поведение надо вынести в класс state, хотя этот класс состояния таки не содержит. Я бы назвал этот паттерн "external behavior" и объединил бы со стратегией.
Re[3]: Выбор шаблона "Состояние" вместо наследования
Z>После имплементации Состояния, сложилось впечатление, что шаблон состояние = Dependency Injection + делегирование поведения другому классу
Z>Это так?
Нет. точнее, не совсем так.
Шаблон State есть ни что иное, как вариант реализации КА (FSM), причем выигрыш от его внедрения заметен только в случаях, когда поведение многих честей системы очень сильно меняется в зависимости от состояния.
Здравствуйте, zfima, Вы писали:
G>>А вообще state нужен для моделирования объектов со встроенным поведением. Например монстры в игре вполне могут по разному вести себя в зависимости от уровня здоровья. Чтобы не делать россыпи if и switch в методах можно воспользоваться паттерном state.
Z>После имплементации Состояния, сложилось впечатление, что шаблон состояние = Dependency Injection + делегирование поведения другому классу
Z>Это так?
Dependency injection здесь ни при чем. Делегируется только поведение, а основной класс управляет переключением состояния.
Re[2]: Выбор шаблона "Состояние" вместо наследования
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, zfima, Вы писали:
Z>>Здравствуйте
Z>>Осваиваю книгу Рефакторинг Мартина Фулера.
Z>>В одном месте заменяет switch. вместо наследования использует шаблон "Состояние": Z>>"... Такой прием позволяет заменить оператор switch полиморфизмом. К сожалению, у этого решения есть маленький недостаток – оно не работает. Фильм за время своего существования может изменить тип, Z>>объект же, пока он жив, изменить свой класс не может. Однако выход есть – паттерн «Состояние» (State pattern [Gang of Four])" стр52.
Z>>Почему надо изменять свой класс?
G>В твоем примере с Movie вполне может оказаться, что тип кина поменяется с Regular на Children, что твоя объектная модель не выдержит.
G>А вообще state нужен для моделирования объектов со встроенным поведением. Например монстры в игре вполне могут по разному вести себя в зависимости от уровня здоровья. Чтобы не делать россыпи if и switch в методах можно воспользоваться паттерном state.
Я правильно понял монстрологию?
public class Monster
{
public IMonsterState MonsterState { set; get; }
public Monster(IMonsterState initMonsterState)
{
MonsterState = initMonsterState;
}
public void HealthImprove()
{
MonsterState.HealthImprove(this);
}
public void HealthDeteriorate()
{
MonsterState.HealthDeteriorate(this);
}
public string ReportStrength()
{
return MonsterState.ReportStrength();
}
}
public interface IMonsterState
{
void HealthImprove(Monster monster);
void HealthDeteriorate(Monster monster);
string ReportStrength();
}
public class VeryStrongMonsterState : IMonsterState
{
public void HealthImprove(Monster monster)
{
//can not improve health
}
public void HealthDeteriorate(Monster monster)
{
monster.MonsterState = new StrongMonsterState();
}
public string ReportStrength()
{
return"Very Strong Monster";
}
}
public class StrongMonsterState : IMonsterState
{
public void HealthImprove(Monster monster)
{
monster.MonsterState = new VeryStrongMonsterState();
}
public void HealthDeteriorate(Monster monster)
{
monster.MonsterState = new WeakMonsterState();
}
public string ReportStrength()
{
return"Strong Monster";
}
}
public class WeakMonsterState : IMonsterState
{
public void HealthImprove(Monster monster)
{
monster.MonsterState = new StrongMonsterState();
}
public void HealthDeteriorate(Monster monster)
{
//can not go down
}
public string ReportStrength()
{
return"Weak Monster";
}
}
Здравствуйте, zfima, Вы писали:
Z>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, zfima, Вы писали:
Z>>>Здравствуйте
Z>>>Осваиваю книгу Рефакторинг Мартина Фулера.
Z>>>В одном месте заменяет switch. вместо наследования использует шаблон "Состояние": Z>>>"... Такой прием позволяет заменить оператор switch полиморфизмом. К сожалению, у этого решения есть маленький недостаток – оно не работает. Фильм за время своего существования может изменить тип, Z>>>объект же, пока он жив, изменить свой класс не может. Однако выход есть – паттерн «Состояние» (State pattern [Gang of Four])" стр52.
Z>>>Почему надо изменять свой класс?
G>>В твоем примере с Movie вполне может оказаться, что тип кина поменяется с Regular на Children, что твоя объектная модель не выдержит.
G>>А вообще state нужен для моделирования объектов со встроенным поведением. Например монстры в игре вполне могут по разному вести себя в зависимости от уровня здоровья. Чтобы не делать россыпи if и switch в методах можно воспользоваться паттерном state.
Z>Я правильно понял монстрологию?
Да, только обычно все пляски с состояниями скрыты от внешних глаз. Когда потребитель класса определяет его поведение через класс поведения это становится стратегией.
Re[4]: Выбор шаблона "Состояние" вместо наследования
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, zfima, Вы писали:
Z>>Здравствуйте, gandjustas, Вы писали:
G>>>Здравствуйте, zfima, Вы писали:
Z>>>>Здравствуйте
Z>>>>Осваиваю книгу Рефакторинг Мартина Фулера.
Z>>>>В одном месте заменяет switch. вместо наследования использует шаблон "Состояние": Z>>>>"... Такой прием позволяет заменить оператор switch полиморфизмом. К сожалению, у этого решения есть маленький недостаток – оно не работает. Фильм за время своего существования может изменить тип, Z>>>>объект же, пока он жив, изменить свой класс не может. Однако выход есть – паттерн «Состояние» (State pattern [Gang of Four])" стр52.
Z>>>>Почему надо изменять свой класс?
G>>>В твоем примере с Movie вполне может оказаться, что тип кина поменяется с Regular на Children, что твоя объектная модель не выдержит.
G>>>А вообще state нужен для моделирования объектов со встроенным поведением. Например монстры в игре вполне могут по разному вести себя в зависимости от уровня здоровья. Чтобы не делать россыпи if и switch в методах можно воспользоваться паттерном state.
Z>>Я правильно понял монстрологию?
G>Да, только обычно все пляски с состояниями скрыты от внешних глаз. Когда потребитель класса определяет его поведение через класс поведения это становится стратегией.
Пляска подразумевает передачу в конструктор класса Monster параметра IMonsterState ?
И, насколько мне позволяют судить мои скудные познания в области шаблонов, различий между стратегией и состоянием больше, чем передачу начального состояния в конструктор:
в стратегии классы, имплементирующие алгоритмы, ничего не знают об их caller, а в состоянии они о нем знают и изменяют его
в стратегии классы, имплементирующие алгоритмы, не заменяют своими "родственниками" никого и ничего, а в состоянии они этим и живут. Как кукушка.
Re[4]: Выбор шаблона "Состояние" вместо наследования
Здравствуйте, gandjustas, Вы писали:
G>Вообще паттерн state говорит о том, что поведение надо вынести в класс state, хотя этот класс состояния таки не содержит. Я бы назвал этот паттерн "external behavior" и объединил бы со стратегией.
Стратегия — это линия поведения, которая не будет меняться по ходу пьесы. А состояние будет.
Объект стратегии неизменный и разделяемый, объект состояния может быть сам по себе переменным.
Так что валить в кучу, пожалуй, не стоит.
Перекуём баги на фичи!
Re[5]: Выбор шаблона "Состояние" вместо наследования
Здравствуйте, zfima, Вы писали:
Z>И, насколько мне позволяют судить мои скудные познания в области шаблонов, различий между стратегией и состоянием больше, чем передачу начального состояния в конструктор:
Z>в стратегии классы, имплементирующие алгоритмы, ничего не знают об их caller, а в состоянии они о нем знают и изменяют его Z>в стратегии классы, имплементирующие алгоритмы, не заменяют своими "родственниками" никого и ничего, а в состоянии они этим и живут. Как кукушка.
Это все теория. С точки зрения кода разница будет очень простая:
1) Стратегия передается классу вызывающим.
2) Состояние изменяется самим классом и скрыто от потребителя.
Сами классы стратегии и состояния почти не отличаются.
Здравствуйте, zfima, Вы писали:
Z>Здравствуйте
Z>Осваиваю книгу Рефакторинг Мартина Фулера.
Это вобщем бесполезная книга сама по себе. Что бы от нее был толк, нужно паралельно смотреть GoF, а примеры рефакторинга в книге Джошуа Кериевски "Рефакторинг с использованием паттернов проектирования", до кучи можно добавить Майкла Физерса "Legacy Code" где он показывает все то же, только под другим углом и с упором на древний код. И еще неплохо посмотреть примеры рефакторинга у Кента Бека "XP:TDD"
Кстати говоря, Кериевски в своей книге очень хорошо показывает применение паттерна State