Шаблонный метод (шаблон проектирования)
Шаблонный метод (англ. Template method) — поведенческий шаблон проектирования, определяющий основу алгоритма и позволяющий наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом. Применимость
УчастникиAbstract class (абстрактный класс) — определяет абстрактные операции, замещаемые в наследниках для реализации шагов алгоритма; реализует шаблонный метод, определяющий скелет алгоритма. Шаблонный метод вызывает замещаемые и другие, определенные в Abstract class, операции. Concrete class (конкретный класс) — реализует замещаемые операции необходимым для данной реализации способом. Concrete class предполагает, что инвариантные шаги алгоритма будут выполнены в AbstractClass. ПримерыВ примерах шаблонный метод реализуется для игр. Исходный текст на языке C++11 /**
* An abstract class that is common to several games in
* which players play against the оthers, but only one is
* playing at a given time.
*/
class GameObject
{
protected:
int PlayersCount;
virtual bool EndOfGame() = 0;
virtual void InitializeGame() = 0;
virtual void MakePlay(int player) = 0;
virtual void PrintWinner() = 0;
public:
/* A template method: */
void PlayOneGame(int playersCount)
{
PlayersCount = playersCount;
InitializeGame();
int j = 0;
while (!EndOfGame()) {
MakePlay(j);
j = (j + 1) % playersCount;
}
PrintWinner();
}
};
class Monopoly : public GameObject
{
protected:
/* Implementation of necessary concrete methods */
void InitializeGame() override
{
// Initialize money
}
void MakePlay(int player) override
{
// Process one turn of player
}
bool EndOfGame() override
{
return true;
}
void PrintWinner() override
{
// Display who won
}
};
class Chess : public GameObject
{
protected:
/* Implementation of necessary concrete methods */
void InitializeGame() override
{
// Put the pieces on the board
}
void MakePlay(int player) override
{
// Process a turn for the player
}
bool EndOfGame() override
{
// Return true if in Checkmate or Stalemate has been reached
return true;
}
void PrintWinner() override
{
// Display the winning player
}
};
int main()
{
GameObject* game = new Monopoly();
game->PlayOneGame(2);
return 0;
}
Исходный текст на языке Java package com.designpatterns.templatemethod;
/* Коды разновидностей игр.
*
* Файл GameCode.java
* */
public enum GameCode {
CHESS,
MONOPOLY
}
/* Абстрактный класс, реализация абстрактных методов которого будет специфичной для каждого вида игры.
*
* Файл Game.java
* */
public abstract class Game {
private int playersAmount;
protected abstract void initializeGame();
protected abstract void playGame();
protected abstract void endGame();
protected abstract void printWinner();
public final void playOneGame(int playersAmount){
setPlayersAmount(playersAmount);
initializeGame();
playGame();
endGame();
printWinner();
}
public void setPlayersAmount(int playersAmount){
this.playersAmount = playersAmount;
}
}
package com.designpatterns.templatemethod;
/* Игра "Шахматы". Специфически только для шахмат реализует методы класса Game.
*
* Файл Chess.java
* */
public class Chess extends Game {
@Override
protected void initializeGame() {
// chess specific initialization actions
}
@Override
protected void playGame() {
// chess specific play actions
}
@Override
protected void endGame() {
// chess specific actions to end a game
}
@Override
protected void printWinner() {
// chess specific actions to print winner
}
}
package com.designpatterns.templatemethod;
/* Игра "Монополия". Специфически только для монополии реализует методы класса Game.
*
* Файл Monopoly.java
* */
public class Monopoly extends Game{
@Override
protected void initializeGame() {
// monopoly specific initialization actions
}
@Override
protected void playGame() {
// monopoly specific play actions
}
@Override
protected void endGame() {
// monopoly specific actions to end a game
}
@Override
protected void printWinner() {
// monopoly specific actions to print winner
}
}
package com.designpatterns.templatemethod;
/* Класс, показывающий работу шаблона проектирования "Шаблонный метод".
*
* Файл GamesManager.java
* */
public class GamesManager {
public static void main (String [] args){
final GameCode gameCode = GameCode.CHESS;
Game game;
switch (gameCode){
case CHESS :
game = new Chess();
break;
case MONOPOLY :
game = new Monopoly();
break;
default :
throw new IllegalStateException();
}
game.playOneGame(2);
}
}
Исходный текст на языке C# /**
* An abstract class that is common to several games in
* which players play against the others, but only one is
* playing at a given time.
*/
namespace Design_Patterns
{
class TemplateMethodPattern
{
internal abstract class GameObject
{
protected int PlayersCount;
abstract protected bool EndOfGame();
abstract protected void InitializeGame();
abstract protected void MakePlay(int player);
abstract protected void PrintWinner();
/* A template method : */
public void PlayOneGame(int playersCount)
{
PlayersCount = playersCount;
InitializeGame();
var j = 0;
while (!EndOfGame())
{
MakePlay(j);
j = (j + 1) % playersCount;
}
PrintWinner();
}
}
//Now we can extend this class in order to implement actual games:
public class Monopoly : GameObject
{
/* Implementation of necessary concrete methods */
protected override void InitializeGame()
{
// Initialize money
}
protected override void MakePlay(int player)
{
// Process one turn of player
}
protected override bool EndOfGame()
{
return true;
}
protected override void PrintWinner()
{
// Display who won
}
/* Specific declarations for the Monopoly game. */
// ...
}
public class Chess : GameObject
{
/* Implementation of necessary concrete methods */
protected override void InitializeGame()
{
// Put the pieces on the board
}
protected override void MakePlay(int player)
{
// Process a turn for the player
}
protected override bool EndOfGame()
{
return true;
// Return true if in Checkmate or Stalemate has been reached
}
protected override void PrintWinner()
{
// Display the winning player
}
/* Specific declarations for the chess game. */
// ...
}
public static void Test()
{
GameObject game = new Monopoly();
game.PlayOneGame(2);
}
}
}
Исходный текст на языке Python from abc import ABCMeta, abstractmethod
class Unit(metaclass=ABCMeta):
"""
Абстрактный отряд. Атрибуты класса, начинающиеся с подчеркивания в python
являются protected
"""
def __init__(self, speed: int) -> None:
"""
Constructor.
:param speed: скорость отряда
"""
self._speed = speed
def hit_and_run(self) -> None:
"""
Шаблонный метод
"""
self._move('вперед')
self._stop()
self._attack()
self._move('назад')
@abstractmethod
def _attack(self) -> None:
pass
@abstractmethod
def _stop(self) -> None:
pass
def _move(self, direction: str) -> None:
"""
Передвижение - у всех отрядов одинаковое, в шаблон не входит
:param direction: направление движения
"""
self._output('движется {} со скоростью {}'.format(direction, self._speed))
def _output(self, message: str) -> None:
"""
Вспомогательный метод вывода сообщений, в шаблон не входит
:param message: выводимое сообщение
"""
print('Отряд типа {} {}'.format(self.__class__.__name__, message))
class Archers(Unit):
"""
Лучники
"""
def _attack(self) -> None:
self._output('обстреливает врага')
def _stop(self) -> None:
self._output('останавливается в 100 шагах от врага')
class Cavalrymen(Unit):
"""
Кавалеристы
"""
def _attack(self) -> None:
self._output('на полном скаку врезается во вражеский строй')
def _stop(self) -> None:
self._output('летит вперед, не останавливаясь')
if __name__ == '__main__':
print('OUTPUT:')
archers = Archers(4)
archers.hit_and_run()
cavalrymen = Cavalrymen(8)
cavalrymen.hit_and_run()
'''
OUTPUT:
Отряд типа Archers движется вперед со скоростью 4
Отряд типа Archers останавливается в 100 шагах от врага
Отряд типа Archers обстреливает врага
Отряд типа Archers движется назад со скоростью 4
Отряд типа Cavalrymen движется вперед со скоростью 8
Отряд типа Cavalrymen летит вперед, не останавливаясь
Отряд типа Cavalrymen на полном скаку врезается во вражеский строй
Отряд типа Cavalrymen движется назад со скоростью 8
'''
Литература
Ссылки
|
Index:
pl ar de en es fr it arz nl ja pt ceb sv uk vi war zh ru af ast az bg zh-min-nan bn be ca cs cy da et el eo eu fa gl ko hi hr id he ka la lv lt hu mk ms min no nn ce uz kk ro simple sk sl sr sh fi ta tt th tg azb tr ur zh-yue hy my ace als am an hyw ban bjn map-bms ba be-tarask bcl bpy bar bs br cv nv eml hif fo fy ga gd gu hak ha hsb io ig ilo ia ie os is jv kn ht ku ckb ky mrj lb lij li lmo mai mg ml zh-classical mr xmf mzn cdo mn nap new ne frr oc mhr or as pa pnb ps pms nds crh qu sa sah sco sq scn si sd szl su sw tl shn te bug vec vo wa wuu yi yo diq bat-smg zu lad kbd ang smn ab roa-rup frp arc gn av ay bh bi bo bxr cbk-zam co za dag ary se pdc dv dsb myv ext fur gv gag inh ki glk gan guw xal haw rw kbp pam csb kw km kv koi kg gom ks gcr lo lbe ltg lez nia ln jbo lg mt mi tw mwl mdf mnw nqo fj nah na nds-nl nrm nov om pi pag pap pfl pcd krc kaa ksh rm rue sm sat sc trv stq nso sn cu so srn kab roa-tara tet tpi to chr tum tk tyv udm ug vep fiu-vro vls wo xh zea ty ak bm ch ny ee ff got iu ik kl mad cr pih ami pwn pnt dz rmy rn sg st tn ss ti din chy ts kcg ve