Mallmetod (designmönster)
mallmetoden |
---|
mallmetoden |
Sorts |
beteendemässiga |
Strukturera |
|
Beskrivs i Design Patterns |
Ja |
En mallmetod är ett beteendedesignmönster som definierar grunden för en algoritm och tillåter efterföljare att omdefiniera några steg i algoritmen utan att ändra dess struktur som helhet.
Tillämplighet
- Engångsanvändning av den invarianta delen av algoritmen, lämnar den föränderliga delen efter arvingarnas gottfinnande.
- Lokalisering och isolering av kod som är gemensam för flera klasser för att undvika dubbelarbete.
- Tillåt arvtagare att utöka koden endast på vissa platser.
Medlemmar
Abstrakt klass (abstrakt klass) - definierar de abstrakta operationerna som ersätts i arvingarna för att implementera stegen i algoritmen; implementerar en mallmetod som definierar skelettet för algoritmen. Mallmetoden anropar den ersatta och andra operationer som definieras i klassen Abstract.
Betongklass (betongklass) - implementerar de ersatta operationerna på det sätt som krävs för denna implementering.
Klassen Concrete antar att de invarianta stegen i algoritmen kommer att utföras i AbstractClass .
Exempel
I exemplen är mallmetoden implementerad för spel.
Källtext i C++11
/**
* En abstrakt klass som är gemensam för flera spel i
* där spelare spelar mot de andra, men bara en
* spelar vid en given tidpunkt.
*/
klass GameObject
{
skyddad :
int PlayersCount ;
virtuell bool EndOfGame () = 0 ;
virtual void InitializeGame () = 0 ;
virtual void MakePlay ( int player ) = 0 ;
virtuell void PrintWinner () = 0 ;
offentliga :
/* En mallmetod: */
void PlayOneGame ( int playersCount )
{
PlayersCount = playersCount ;
InitializeGame ();
int j = 0 ;
while ( ! EndOfGame ()) {
MakePlay ( j );
j = ( j + 1 ) % playersCount ;
}
tryckvinnare ();
}
};
klass Monopol : offentligt GameObject
{
skyddad :
/* Implementering av nödvändiga konkreta metoder */
void InitializeGame () åsidosätt
{
// Initiera pengar
}
void MakePlay ( int player ) åsidosätt
{
// Bearbeta en spelares varv
}
bool EndOfGame () åsidosätta
{
returnera sant ;
}
void PrintWinner () åsidosättande
{
// Visa vem som vann
}
};
klass schack : offentligt GameObject
{
skyddad :
/* Implementering av nödvändiga konkreta metoder */
void InitializeGame () åsidosätt
{
// Lägg bitarna på brädet
}
void MakePlay ( int player ) åsidosätt
{
// Bearbeta en tur för spelaren
}
bool EndOfGame () åsidosätta
{
// Returnera sant om i schackmatt eller dödläge har uppnåtts
returnera sant ;
}
void PrintWinner () åsidosättande
{
// Visa den vinnande spelaren
}
};
int main ()
{
GameObject * spel = nytt Monopol ();
spel -> PlayOneGame ( 2 );
returnera 0 ;
}
Java-källa
paket com.designpatterns.templatemethod ;
/* Spelvariantkoder.
*
* Arkiv GameCode.java
* */
public enum GameCode {
CHESS ,
MONOPOLY
}
/* En abstrakt klass vars implementering av abstrakta metoder kommer att vara specifik för varje typ av spel.
*
* Arkiv Game.java
* */
offentlig abstrakt klass Spel {
privata int -spelareBelopp ;
skyddad abstrakt void initializeGame ();
skyddad abstrakt void playGame ();
skyddad abstrakt void endGame ();
skyddad abstrakt void printWinner ();
public final void playOneGame ( int playersAmount ){
setPlayersAmount ( playersAmount );
initializeGame ();
playGame ();
slutspel ();
printWinner ();
}
public void setPlayersAmount ( int playersAmount ){
detta . playersAmount = playersAmount ;
}
}
paket com.designpatterns.templatemethod ;
/* Spelet "Schack". Specifikt för schack, implementerar metoderna i spelklassen.
*
* Fil Chess.java
* */
public class Chess extends Game {
@Override
protected void initializeGame () {
// schackspecifika initieringsåtgärder
}
@Override
protected void playGame () {
// schackspecifika spelåtgärder
}
@Override
protected void endGame () {
// schackspecifika åtgärder för att avsluta ett spel
}
@Override
protected void printWinner () {
// schackspecifika åtgärder för att skriva ut vinnaren
}
}
paket com.designpatterns.templatemethod ;
/* Monopolspel. Specifik för monopol, implementerar metoderna i spelklassen.
*
* Fil Monopoly.java
* */
offentlig klass Monopol utökar Game {
@Override
protected void initializeGame () {
// monopolspecifika initieringsåtgärder
}
@Override
protected void playGame () {
// monopolspecifika spelåtgärder
}
@Override
protected void endGame () {
// monopolspecifika åtgärder för att avsluta ett spel
}
@Override
protected void printWinner () {
// monopolspecifika åtgärder för att skriva ut vinnaren
}
}
paket com.designpatterns.templatemethod ;
/* En klass som visar hur mallmetodens designmönster fungerar.
*
* Fil GamesManager.java
* */
offentlig klass GamesManager {
public static void main ( String [] args ){
final GameCode gameCode = GameCode . CHESS ;
spel spel ;
switch ( gameCode ){
case CHESS :
game = new Chess ();
bryta ;
case MONOPOLY :
spel = nytt Monopol ();
bryta ;
default :
throw new IllegalStateException ();
}
spel . playOneGame ( 2 );
}
}
Källtext i C#
/**
* En abstrakt klass som är gemensam för flera spel i
* där spelare spelar mot de andra, men bara en
* spelar vid en given tidpunkt.
*/
namespace Design_Patterns
{
class TemplateMethodPattern
{
intern abstrakt klass GameObject
{
protected int PlayersCount ;
abstrakt skyddad bool EndOfGame ();
abstrakt skyddat void InitializeGame ();
abstrakt skyddad void MakePlay ( int player );
abstrakt skyddad void PrintWinner ();
/* En mallmetod: */
public void PlayOneGame ( int playersCount )
{
PlayersCount = playersCount ;
InitializeGame ();
var j = 0 ;
while (! EndOfGame ())
{
MakePlay ( j );
j = ( j + 1 ) % playersCount ;
}
tryckvinnare ();
}
}
//Nu kan vi utöka den här klassen för att implementera faktiska spel:
public class Monopoly : GameObject
{
/* Implementering av nödvändiga konkreta metoder */
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 ()
{
// Visa vem som vann
}
/* Specifika deklarationer för Monopolspelet. */
// ...
}
public class Chess : GameObject
{
/* Implementering av nödvändiga konkreta metoder */
protected override void InitializeGame ()
{
// Lägg pjäserna på brädet
}
protected override void MakePlay ( int player )
{
// Process a turn for the player
}
protected override bool EndOfGame ()
{
return true ;
// Returnera sant om i schackmatt eller dödläge har uppnåtts
}
protected override void PrintWinner ()
{
// Visa den vinnande spelaren
}
/* Specifika deklarationer för schackspelet. */
// ...
}
public static void Test ()
{
GameObject game = new Monopol ();
spel . PlayOne Game ( 2 );
}
}
}
Källkod i Python
från abc import ABCMeta , abstraktmetod
class Unit ( metaclass = ABCMeta ):
"""
En abstrakt enhet. Klassattribut som börjar med ett understreck i python
är skyddade
"""
def __init__ ( själv , hastighet : int ) -> Ingen :
"""
Konstruktör.
:param hastighet: enhetshastighet
" ""
själv ._speed = hastighet
def hit_and_run ( self ) -> None :
"""
Mallmetod
"""
self . _move ( 'framåt' )
själv . _stopp ()
själv . _attack ()
själv . _move ( 'bakåt' )
@abstractmethod
def _attack ( self ) -> None :
pass
@abstractmethod
def _stop ( self ) -> Ingen :
godkänt
def _move ( self , direction : str ) -> Ingen :
"""
Rörelse - alla enheter har samma, ingår inte i mallen
:param riktning: rörelseriktning
"""
self ._output ( ' flyttar {} med hastighet {} ' . format ( direction , self . _speed ))
def _output ( self , message : str ) -> None :
"""
Meddelandeutgångshjälpmetod, ingår inte i mallen
:param meddelande: meddelande att skriva ut
"""
print ( 'Trupp av typen {} {} ' . format ( själv . __klass__ . __namn__ , meddelande ))
klass Bågskyttar ( Enhet ):
"""
Bågskyttar
"""
def _attack ( self ) -> None :
self . _output ( 'bomberar fienden' )
def _stop ( själv ) -> Ingen :
själv . _output ( 'stoppar 100 fot från fienden' )
klass Kavallerimän ( Enhet ):
"""
Kavallerimän
"""
def _attack ( self ) -> None :
self . _output ( 'Kraskar in i fiendeformation i full galopp' )
def _stop ( själv ) -> Ingen :
själv . _output ( 'flyger framåt utan att stanna' )
if __name__ == '__main__' :
print ( 'OUTPUT:' )
Archers = Archers ( 4 )
Archers . hit_and_run ()
cavalrymen = Cavalrymen ( 8 )
cavalrymen . hit_and_run ()
'''
UTGÅNG: Enhet av
bågskyttetyp rör sig framåt med en hastighet av 4 enheter av
bågskyttetyp 100 steg från en fiende
Enhet av bågskyttetyp skjuter mot en fientlig enhet
av bågskyttetyp rör sig bakåt med en hastighet av 4
enhetsdrag av kavalleristtyp framåt med en hastighet av 8
Cavalrymen-typ enhet flyger framåt utan att stanna
Cavalrymen-typ enhet i full galopp kraschar in i fiendens formation
Cavalrymen-typ enhet rör sig bakåt med en hastighet av 8
'''
Litteratur
- E. Gamma, R. Helm, R. Johnson, J. Vlissides . Tekniker för objektorienterad design. Designmönster = Designmönster: Element av återanvändbar objektorienterad programvara. - St Petersburg. : "Peter" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (även ISBN 5-272-00355-1 )
Länkar