Sablon módszer (tervezési minta)
sablon módszer |
---|
sablon módszer |
Típusú |
viselkedési |
Szerkezet |
|
Leírása: Tervezési minták |
Igen |
A sablon módszer egy viselkedési tervezési minta , amely meghatározza az algoritmus alapját, és lehetővé teszi az utódok számára az algoritmus egyes lépéseinek újradefiniálását anélkül, hogy a szerkezet egészét megváltoztatná.
Alkalmazhatóság
- Az algoritmus invariáns részének egyszeri használata, a változó részt az örökösök belátására hagyva.
- A több osztályban közös kód lokalizálása és elkülönítése a párhuzamosságok elkerülése érdekében.
- Csak bizonyos helyeken engedélyezze az örökösök számára a kód kiterjesztését.
Tagok
Absztrakt osztály (absztrakt osztály) - meghatározza az absztrakt műveleteket, amelyeket az örökösökben helyettesítenek az algoritmus lépéseinek végrehajtása érdekében; sablon módszert valósít meg, amely meghatározza az algoritmus vázát. A template metódus meghívja a helyettesített és az Abstract osztályban meghatározott egyéb műveleteket.
Konkrét osztály (concrete class) - a helyettesített műveleteket az ehhez a megvalósításhoz szükséges módon valósítja meg.
A Concrete osztály feltételezi, hogy az algoritmus invariáns lépései az AbstractClass -ban lesznek végrehajtva .
Példák
A példákban a sablon módszert a játékokhoz valósítottuk meg.
Forrásszöveg C++11 nyelven
/**
* Egy absztrakt osztály, amely több olyan játékra is jellemző,
amelyekben * a játékosok a többiek ellen játszanak, de
egy adott időpontban csak egy játszik *.
*/
osztályú GameObject
{
védett :
int PlayersCount ;
virtual bool EndOfGame () = 0 ;
virtual void InitializeGame () = 0 ;
virtuális void MakePlay ( int player ) = 0 ;
virtuális üres Nyertes Nyertes () = 0 ;
nyilvános :
/* Egy sablon módszer: */
void PlayOneGame ( int gamesCount )
{
PlayersCount = PlayersCount ;
InitializeGame ();
int j = 0 ;
while ( ! EndOfGame ()) {
MakePlay ( j );
j = ( j + 1 ) % játékosok száma ;
}
nyomdanyertes ();
}
};
osztály Monopólium : nyilvános GameObject
{
védett :
/* A szükséges konkrét módszerek megvalósítása */
void InitializeGame () felülbírálása
{
// Pénz inicializálása
}
void MakePlay ( int player ) felülírás
{
// A játékos egy körének feldolgozása
}
bool EndOfGame () felülbírálása
{
return true ;
}
érvénytelen PrintWinner () felülbírálása
{
// Jelenítse meg, ki nyert
}
};
osztály Sakk : nyilvános GameObject
{
védett :
/* A szükséges konkrét módszerek megvalósítása */
void InitializeGame () felülbírálása
{
// Tedd fel a darabokat a táblára
}
void MakePlay ( int player ) felülírás
{
// A játékos körének feldolgozása
}
bool EndOfGame () felülbírálása
{
// Igaz visszatérés, ha a Sakk-mattban vagy a Patthelyzetben elértük az igazat
return true ;
}
érvénytelen PrintWinner () felülbírálása
{
// A nyertes játékos megjelenítése
}
};
int main ()
{
GameObject * játék = új Monopoly ();
játék -> PlayOneGame ( 2 );
return 0 ;
}
Java forrás
csomag com.designpatterns.templatemethod ;
/* Játékváltozat kódok.
*
* GameCode.java fájl
* */
public enum GameCode {
CHESS ,
MONOPOLY
}
/* Egy absztrakt osztály, amelynek absztrakt metódusainak megvalósítása minden játéktípusra jellemző.
*
* Game.java fájl
* */
nyilvános absztrakt osztály játék {
privát int játékosokAmount ;
védett absztrakt void inicializálásGame ();
védett absztrakt void playGame ();
védett absztrakt void endGame ();
védett absztrakt üres nyomtatás Nyertes ();
public final void playOneGame ( int gamesAmount ){
setPlayersAmount ( gamesAmount );
inicializeGame ();
playGame ();
endGame ();
printWinner ();
}
public void setPlayersAmount ( int gamesAmount ){
this . playerAmount = playerAmount ;
}
}
csomag com.designpatterns.templatemethod ;
/* „Sakk” játék. Kifejezetten a sakkra, a Játék osztály módszereit valósítja meg.
*
* Chess.java fájl
* */
public class A sakk meghosszabbítja a játékot {
@Override
protected void inicializeGame () {
// sakkspecifikus inicializálási műveletek
}
@A
védett void játék felülbírálása () { // sakkspecifikus játékműveletek }
@A
védett void endGame () felülbírálása {
// sakkspecifikus műveletek a játék befejezéséhez
}
@Override
protected void printWinner () {
// sakkspecifikus műveletek a győztes nyomtatásához
}
}
csomag com.designpatterns.templatemethod ;
/* Monopoly játék. A monopóliumra jellemző, a Game osztály metódusait valósítja meg.
*
* Monopoly.java fájl
* */
public class A Monopoly kiterjeszti a játékot {
@Override
protected void inicializeGame () {
// monopóliumspecifikus inicializálási műveletek
}
@Override
protected void playGame () {
// monopóliumspecifikus játékműveletek
}
@Override
protected void endGame () {
// monopóliumspecifikus műveletek a játék befejezéséhez
}
@Override
protected void printWinner () {
// monopóliumspecifikus műveletek a győztes nyomtatásához
}
}
csomag com.designpatterns.templatemethod ;
/* A Template Method tervezési minta működését bemutató osztály.
*
* GamesManager.java fájl
* */
nyilvános osztály GamesManager {
public static void main ( String [] args ){
final GameCode gameCode = GameCode . SAKK ;
játék játék ;
switch ( gameCode ){
case CHESS :
game = new Chess ();
szünet ;
case MONOPOLY :
játék = new Monopoly ();
szünet ;
alapértelmezett :
dobj új IllegalStateException ();
}
játék . playOneGame ( 2 );
}
}
Forrásszöveg C# nyelven
/**
* Egy absztrakt osztály, amely több olyan játékra is jellemző,
amelyekben * a játékosok a többiek ellen játszanak, de
egy adott időpontban csak egy játszik *.
*/
névtér Design_Patterns
{
class TemplateMethodPattern
{
belső absztrakt osztály GameObject
{
protected int PlayersCount ;
absztrakt védett bool EndOfGame ();
absztrakt védett void InitializeGame ();
absztrakt védett void MakePlay ( int player );
absztrakt védett üres Nyertes ();
/* Egy sablon metódus: */
public void PlayOneGame ( int gamesCount )
{
PlayersCount = PlayersCount ;
InitializeGame ();
var j = 0 ;
while (! EndOfGame ())
{
MakePlay ( j );
j = ( j + 1 ) % játékosok száma ;
}
nyomdanyertes ();
}
}
//Most kibővíthetjük ezt az osztályt a tényleges játékok megvalósítása érdekében:
public class Monopoly : GameObject
{
/* A szükséges konkrét módszerek megvalósítása */
védett felülírás void InitializeGame ()
{
// Pénz inicializálása
}
védett felülírás void MakePlay ( int player )
{
// A játékos egy körének feldolgozása
}
protected override bool EndOfGame ()
{
return true ;
}
védett felülírás void Nyomtatási nyertes ()
{
// Megmutatja, ki nyert
}
/* Konkrét nyilatkozatok a Monopoly játékhoz. */
// ...
}
nyilvános osztály sakk : GameObject
{
/* A szükséges konkrét módszerek megvalósítása */
Protected override void InitializeGame ()
{
// Tedd a figurákat a táblára
}
védett felülírás void MakePlay ( int player )
{
// A játékos körének feldolgozása
}
protected override bool EndOfGame ()
{
return true ;
// Igazat ad vissza, ha a sakk-matt vagy a patthelyzet elérkezett
}
védett felülírás void PrintWinner ()
{
// A nyertes játékos megjelenítése
}
/* Konkrét nyilatkozatok a sakkjátszmához. */
// ...
}
public static void Teszt ()
{
GameObject játék = new Monopoly ();
játék . PlayOne játék ( 2 );
}
}
}
Forráskód Pythonban
abc importból ABCMeta , abstractmethod _
osztály Egység ( metaclass = ABCMeta ):
"""
Absztrakt egység. A pythonban aláhúzással kezdődő osztályattribútumok
védettek
"""
def __init__ ( self , speed : int ) -> None :
"""
Konstruktor.
:param speed: egységsebesség
" ""
self ._speed = sebesség
def hit_and_run ( self ) -> None :
"""
Sablon metódus
"""
self . _move ( 'előre' )
self . _stop ()
self . _attack ()
self . _move ( 'hátra' )
@abstractmethod
def _attack ( self ) -> None :
pass
@abstractmethod
def _stop ( self ) -> None :
pass
def _move ( self , direction : str ) -> None :
"""
Mozgás - minden egység ugyanaz, nem szerepel a sablonban
:param irány: mozgás iránya
"""
self ._output ( ' mozog {} sebességgel {} ' . formátum ( irány , saját . _sebesség ))
def _output ( self , message : str ) -> None :
"""
Üzenetkimenet segítő metódus, nem szerepel a sablonban
:param üzenet: nyomtatandó üzenet
"""
print ( 'Squad of type: {} {} ' . format ( self . __class__ . __name__ , message ))
osztály íjászok ( egység ):
"""
Íjászok
"""
def _attack ( self ) -> None :
self . _output ( 'bombázza az ellenséget' )
def _stop ( self ) -> None :
self . _output ( 'megáll 100 lábra az ellenségtől' )
osztályú lovas katonák ( egység ):
"""
Lovas katonák
"""
def _attack ( self ) -> None :
self . _output ( 'Teljes vágtában ütközik az ellenséges alakulatba' )
def _stop ( self ) -> None :
self . _output ( 'megállás nélkül előre repül' )
if __name__ == '__main__' :
print ( 'OUTPUT:' )
íjászok = Íjászok ( 4 )
íjászok . hit_and_run ()
cavalrymen = Cavalrymen ( 8 )
cavalrymen . hit_and_run ()
''''
KIMENET:
Az íjász típusú egység 4
nyilas típusú egység megáll 100 lépésre az ellenségtől
Íjász típusú egység lő egy ellenségre Az íjász típusú egység 4
lovassági típusú egység mozgási sebességgel mozog hátra
előre 8-as sebességgel
Lovassági típusú egység megállás nélkül repül előre
Lovassági típusú egység teljes vágtában az ellenséges alakulatba ütközik Lovas típusú egység 8
''' sebességgel hátrafelé halad
Irodalom
- E. Gamma, R. Helm, R. Johnson, J. Vlissides . Objektumorientált tervezés technikái. Tervezési minták = Design Patterns: Az újrafelhasználható objektum-orientált szoftver elemei. - Szentpétervár. : "Péter" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . ( ISBN 5-272-00355-1 is )
Linkek