Metoda șablonului (model de proiectare)
metoda șablonului |
---|
metoda șablonului |
Tip de |
comportamental |
Structura |
|
Descris în Design Patterns |
da |
O metodă șablon este un model de proiectare comportamentală care definește baza unui algoritm și le permite succesorilor să redefinească unii pași ai algoritmului fără a-și schimba structura în ansamblu.
Aplicabilitate
- Utilizarea unică a părții invariante a algoritmului, lăsând partea care se schimbă la latitudinea moștenitorilor.
- Localizarea și izolarea codului comun mai multor clase pentru a evita duplicarea.
- Permiteți moștenitorilor să extindă codul numai în anumite locuri.
Membrii
Clasa abstracta (clasa abstracta) - defineste operatiunile abstracte care sunt inlocuite in mostenitori pentru a implementa etapele algoritmului; implementează o metodă șablon care definește scheletul algoritmului. Metoda șablon apelează operațiile înlocuite și alte operațiuni definite în clasa Abstract.
Clasa de beton (clasa de beton) - implementeaza operatiile inlocuite in modul necesar acestei implementari.
Clasa Concrete presupune că pașii invarianți ai algoritmului vor fi executați în AbstractClass .
Exemple
În exemple, metoda șablonului este implementată pentru jocuri.
Text sursă în C++11
/**
* O clasă abstractă care este comună mai multor jocuri în
care * jucători joacă împotriva celorlalți, dar numai unul
* joacă la un moment dat.
*/
clasa GameObject
{
protejat :
int PlayersCount ;
virtual bool EndOfGame () = 0 ;
virtual void InitializeGame () = 0 ;
virtual void MakePlay ( int player ) = 0 ;
virtual void PrintWinner () = 0 ;
public :
/* O metodă de șablon: */
void PlayOneGame ( int playersCount )
{
PlayersCount = playersCount ;
InitializeGame ();
int j = 0 ;
în timp ce ( ! EndOfGame ()) {
MakePlay ( j );
j = ( j + 1 ) % jucătoriNumăr ;
}
printwinner ();
}
};
clasa Monopoly : GameObject public
{
protejat :
/* Implementarea metodelor concrete necesare */
void InitializeGame () anulare
{
// Inițializați bani
}
void MakePlay ( int player ) anulare
{
// Procesează o tură de jucător
}
bool EndOfGame () anulare
{
returnează adevărat ;
}
anulează anularea PrintWinner () .
{
// Afișează cine a câștigat
}
};
clasa de șah : GameObject public
{
protejat :
/* Implementarea metodelor concrete necesare */
void InitializeGame () anulare
{
// Pune piesele pe tabla
}
void MakePlay ( int player ) anulare
{
// Procesează o tură pentru jucător
}
bool EndOfGame () anulare
{
// Returnează true dacă în Checkmate sau Stalemate a fost atins
return true ;
}
anulează anularea PrintWinner () .
{
// Afișează jucătorul câștigător
}
};
int main ()
{
GameObject * joc = nou Monopoly ();
joc -> PlayOneGame ( 2 );
returnează 0 ;
}
Sursa Java
pachet com.designpatterns.templatemethod ;
/* Coduri de variante ale jocului.
*
* Fișier GameCode.java
* */
enumerare publică GameCode {
ȘAH ,
MONOPOL
}
/* O clasă abstractă a cărei implementare a metodelor abstracte va fi specifică fiecărui tip de joc.
*
* Fișier Game.java
* */
Clasă abstractă publică Joc {
private int playersAmount ;
void abstract protejat initializeGame ();
protejat abstract void playGame ();
void abstract protejat endGame ();
print void abstract protejatWinner ();
public final void playOneGame ( int playersAmount ){
setPlayersAmount ( playersAmount );
initializeGame ();
playGame ();
final de joc ();
printWinner ();
}
public void setPlayersAmount ( int playersAmount ){
aceasta . playersAmount = playersAmount ;
}
}
pachet com.designpatterns.templatemethod ;
/* Jocul „Șah”. Specific pentru șah, implementează metodele clasei Game.
*
* Fișier Chess.java
* */
Șahul de clasă publică extinde jocul {
@Override
protected void initializeGame () {
// acțiuni de inițializare specifice șahului
}
@Override
protected void playGame () {
// acțiuni de joc specifice șahului
}
@Override
protected void endGame () {
// acțiuni specifice de șah pentru a încheia un joc
}
@Override
protected void printWinner () {
// acțiuni specifice de șah pentru a imprima câștigătorul
}
}
pachet com.designpatterns.templatemethod ;
/* Joc de monopol. Specific monopolului, implementează metodele clasei Game.
*
* Fișier Monopoly.java
* */
Monopoly de clasă publică extinde jocul {
@Override
protected void initializeGame () {
// acțiuni de inițializare specifice monopolului
}
@Override
protected void playGame () {
// acțiuni de joc specifice monopolului
}
@Override
protected void endGame () {
// monopolizare acțiuni specifice pentru a încheia un joc
}
@Override
protected void printWinner () {
// acțiuni specifice de monopol pentru a imprima câștigătorul
}
}
pachet com.designpatterns.templatemethod ;
/* O clasă care arată cum funcționează modelul de proiectare al Metodei șablonului.
*
* Fișier GamesManager.java
* */
GamesManager de clasă publică {
public static void main ( String [] args ){
final GameCode gameCode = GameCode . ȘAH ;
joc joc ;
switch ( gameCode ){
case ȘAH :
joc = șah nou (); rupe ; caz MONOPOLY : joc = monopol nou (); rupe ; implicit : aruncă o nouă excepție IllegalStateException (); }
joc . playOneGame ( 2 );
}
}
Text sursă în C#
/**
* O clasă abstractă care este comună mai multor jocuri în
care * jucători joacă împotriva celorlalți, dar numai unul
* joacă la un moment dat.
*/
namespace Design_Patterns
{
class TemplateMethodPattern
{
intern abstract class GameObject
{
protected int PlayersCount ;
abstract protejat bool EndOfGame ();
abstract protejat void InitializeGame ();
abstract protejat void MakePlay ( int player );
abstract protejat void PrintWinner ();
/* O metodă de șablon: */
public void PlayOneGame ( int playersCount )
{
PlayersCount = playersCount ;
InitializeGame ();
var j = 0 ;
while (! EndOfGame ())
{
MakePlay ( j );
j = ( j + 1 ) % jucătoriNumăr ;
}
printwinner ();
}
}
//Acum putem extinde această clasă pentru a implementa jocurile reale:
public class Monopoly : GameObject
{
/* Implementarea metodelor concrete necesare */
protected override void InitializeGame ()
{
// Initialize money
}
protected override void MakePlay ( int player )
{
// Procesează o tură de jucător
}
protected override bool EndOfGame ()
{
return true ;
}
protected override void PrintWinner ()
{
// Afișează cine a câștigat
}
/* Declarații specifice pentru jocul Monopoly. */
// ...
}
Șah de clasă publică : GameObject {
/* Implementarea metodelor concrete necesare */
protected override void InitializeGame ()
{
// Pune piesele pe tabla
}
protected override void MakePlay ( int player )
{
// Procesează o tură pentru jucător
}
protected override bool EndOfGame ()
{
return true ;
// Returnează adevărat dacă în șah-mat sau impas a fost atins
}
protected override void PrintWinner ()
{
// Afișează jucătorul câștigător
}
/* Declarații specifice pentru jocul de șah. */
// ...
}
public static void Test ()
{
GameObject game = new Monopoly ();
joc . Jocul PlayOne ( 2 );
}
}
}
Cod sursă în Python
din abc import ABCMeta , abstractmethod
class Unit ( metaclass = ABCMeta ):
"""
O unitate abstractă. Atributele clasei care încep cu un caracter de subliniere în Python
sunt protejate
"""
def __init__ ( self , speed : int ) -> None :
"""
Constructor.
:param speed: unitate de viteză
" ""
self ._speed = viteză
def hit_and_run ( self ) -> None :
"""
Metoda șablonului
"""
self . _muta ( 'înainte' )
sine . _stop ()
sine . _atac ()
sine . _mușcare ( „înapoi” )
@abstractmethod
def _attack ( self ) -> None :
trece
@abstractmethod
def _stop ( self ) -> None :
trece
def _move ( self , direction : str ) -> None :
"""
Mișcare - toate unitățile au aceeași, neincluse în șablon
:param direction: direcția de mișcare
"""
self ._output ( ' se mișcă {} la viteza {} ' . format ( direcție , self . _viteză ))
def _output ( self , message : str ) -> None :
"""
Metoda de ajutor pentru ieșirea mesajului, nu este inclusă în șablon
:param mesaj: mesaj de tipărit
„””
print ( „Echipă de tip {} {} ' . format ( self . __class__ . __name__ , mesaj ))
clasa Arcași ( Unitate ):
"""
Arcași
"""
def _atack ( self ) -> None :
self . _ieșire ( „bombă inamicul” )
def _stop ( self ) -> None :
self . _ieșire ( „se oprește la 100 de picioare de inamic” )
clasa cavaleristi ( unitate ):
"""
cavaleristi
"""
def _atack ( self ) -> None :
self . _output ( „Se prăbușește în formația inamică la galop complet” )
def _stop ( self ) -> None :
self . _output ( 'zboară înainte fără oprire' )
if __name__ == '__main__' :
print ( 'OUTPUT:' )
arcași = Arcași ( 4 )
arcași . hit_and_run ()
cavalrymen = Cavalrymen ( 8 )
cavalrymen . hit_and_run ()
'''
IEȘIRE:
Unitatea de tip arcași se deplasează înainte cu o viteză de 4
unitatea de tip arcași se oprește la 100 de pași de la o
unitate de tip arcași inamic trage într-o
unitate de tip arcași inamic se mișcă înapoi cu o viteză de 4
mișcări de unități de tip cavaleresc înainte cu o viteză de 8
unitatea de tip cavaleresc zboară înainte fără oprire
Unitatea de tip cavaleresc la galop complet se prăbușește în formația inamică
Unitatea de tip cavaleresc se deplasează înapoi cu o viteză de 8
inchi
Literatură
- E. Gamma, R. Helm, R. Johnson, J. Vlissides . Tehnici de proiectare orientată pe obiecte. Design Patterns = Design Patterns: Elements of Reusable Object-Oriented Software. - Sankt Petersburg. : „Petru” , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (și ISBN 5-272-00355-1 )
Link -uri