Tolmács (tervezési minta)

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2017. április 5-én felülvizsgált verziótól ; az ellenőrzések 12 szerkesztést igényelnek .
Tolmács
tolmács
Típusú viselkedési
Célja megold egy gyakran előforduló, változékony problémát
Leírása: Tervezési minták Igen

Az interpreter egy viselkedési tervezési minta , amely  egy gyakran előforduló, de változékony feladatot old meg. Más néven Little (Small) Language

Probléma

Van egy gyakran előforduló, változékony feladat.

Megoldás

Hozzon létre egy tolmácsot, amely megoldja ezt a problémát.

Előnyök

A nyelvtan könnyen bővíthetővé, módosíthatóvá válik, az absztrakt szintaxisfa csomópontjait leíró osztályok megvalósításai hasonlóak (könnyen kódolhatók). Könnyen módosíthatja a kifejezések kiértékelésének módját.

Hátrányok

A sok szabályt tartalmazó nyelvtan fenntartása nehéz.

Példa

A karakterláncok minta szerinti keresésének feladatát a nyelv grammatikáját definiáló interpreter létrehozásával lehet megoldani. A "Kliens" egy absztrakt szintaktikai fa formájában épít fel egy mondatot, amelynek csomópontjaiban "TerminalExpression" és "NonterminalExpression" (rekurzív) osztályú objektumok találhatók, majd a "Client" inicializálja a kontextust és meghívja a Parse( Kontextus) művelet. Minden "NonterminalExpression" típusú csomópont meghatároz egy elemzési műveletet minden egyes részkifejezéshez. A "NonTerminalExpression" osztály esetében a Parse művelet határozza meg a rekurzió alapját. Az "AbstractExpression" meghatározza az absztrakt elemzési műveletet, amely az absztrakt szintaxisfa összes csomópontjára jellemző. A "Kontextus" globális információkat tartalmaz a tolmács számára.

C#

Forrásszöveg C# nyelven a rendszer használatával ; a System.Collections használatával ; névtér DoFactory.GangOfFour.Interpreter.Structural { class Program { static void Main () { var context = new Context (); var input = new MyExpression (); var kifejezés = new OrExpression { Left = new EqualsExpression { Left = input , Right = new MyExpression { Value = "4" } }, Right = new EqualsExpression { Left = input , Right = new MyExpression { Érték = "négy" } } } ; // Kimenet: true input . Érték = "négy" ; kifejezés . értelmezni ( kontextus ); Konzol . WriteLine ( context.result.pop ( ) ) ; _ // Kimenet: false input . Érték = "44" ; kifejezés . értelmezni ( kontextus ); Konzol . WriteLine ( context.result.pop ( ) ) ; _ } } class Kontextus { public Stack < string > Eredmény = new Verem < string >(); } interface Kifejezés { void Interpret ( kontextus ) ; } absztrakt osztály OperatorExpression : Kifejezés { public Expression Left { private get ; készlet ; } public Expression Right { private get ; készlet ; } public void Értelmezés ( Környezetkörnyezet ) { Balra . _ értelmezni ( kontextus ); string leftValue = kontextus . eredmény . pop (); Igaz . értelmezni ( kontextus ); string rightValue = kontextus . eredmény . pop (); DoInterpret ( kontextus , leftValue , rightValue ); } védett absztrakt void DoInterpret ( Kontextus kontextus , string leftValue , string rightValue ); } class EqualsExpression : OperatorExpression { protected override void DoInterpret ( Kontextus kontextus , string leftValue , string rightValue ) { context . eredmény . Push ( leftValue == rightValue ? "true" : "false" ); } } class OrExpression : OperatorExpression { protected override void DoInterpret ( kontextus kontextus , string leftValue , string rightValue ) { kontextus . eredmény . Push ( leftValue == "igaz" || rightValue == "igaz" ? "igaz" : "hamis" ); } } class MyExpression : Kifejezés { public string Érték { private get ; készlet ; } public void Interpret ( Context context ) { context . eredmény . Push ( Érték ); } } }

Python

Forráskód Pythonban __doc__ = ''' Logikai kifejezések kiértékelésére és kezelésére szolgáló rendszer. Példa a Gang of Four-ból - "Tervezési minták: Az újrafelhasználható objektum-orientált szoftver elemei" ''' abc importból ABCMeta , abstractmethod _ osztály Kontextus : """ A """ értelmező futási környezete def __init__ ( self , változók : dict = {}) -> Nincs : """ Konstruktor. :param változók: a változónevek és azok értékei közötti egyezések szótára " "" self ._variables = változók osztály KontextusKivétel ( Kivétel ): """ Kivételt adunk, ha helytelen munkát végeztek ezzel a """ osztályzattal def lookup ( self , name : str ) -> bool : """ Lekéri a változó értékét a neve alapján :param név: változó neve """ , ha a név önmagában . _variables : önmagát adja vissza . _variables [ név ] önmagát emeli . ContextException ( 'Ismeretlen változó {} ' . formátum ( név )) def assign ( self , name : str , value : bool ) -> None : """ Értéket rendel egy változóhoz a neve alapján :param name: változó neve :param value: változó értéke " "" self ._variables [ név ] = érték osztály BooleanExp ( metaclass = ABCMeta ): """ Absztrakt logikai kifejezés """ @abstractmethod def arvo _ _ _ _ _ _ _ _ _ _ _ _ _ _ osztály ConstantExp ( BooleanExp ): """ Logikai konstans """ def __init__ ( self , value : bool ): """ Konstruktor. :param value: kifejezés értéke (igaz vagy hamis) "" " self ._value = érték def értékel ( self , kontextus : Context ): return self . _érték osztály VariableExp ( BooleanExp ): """ Logikai változó (a változók értéke az értelmező környezeti objektumban van tárolva) """ def __init__ ( self , name : str ) -> None : """ Konstruktor. :param név: változó neve " "" self ._name = név def értékel ( self , kontextus : kontextus ) -> bool : kontextus visszaadása . keresés ( self . _name ) osztály BinaryOperationExp ( BooleanExp , metaclass = ABCMeta ): """ Absztrakt osztály bináris logikai műveletekhez """ def __init__ ( self , balra : BooleanExp , jobbra : BooleanExp ) -> None : """ Konstruktor. :param left: left operandus :param right: right operandus " " " self ._left = left self ._right = right osztály AndExp ( BinaryOperationExp ): """ Konjunkció """ def értékel ( self , kontextus : kontextus ) -> bool : önmagát adja vissza . _balra . értékeli ( kontextus ) és önmagát . _jobbra . értékelni ( kontextus ) osztály OrExp ( BinaryOperationExp ): """ Disjunkció """ def értékel ( self , kontextus : kontextus ) -> bool : önmagát adja vissza . _balra . értékeli ( kontextus ) vagy önmagát . _jobbra . értékelni ( kontextus ) osztály NotExp ( BooleanExp ): """ Negatív """ def __init__ ( self , operandus : BooleanExp ) -> None : """ Konstruktor. :param operandus: operandus, amelyre a """ művelet önállóan kerül alkalmazásra _operand = operandus def értékel ( self , kontextus : kontextus ) -> bool : return not self . _operand . értékelni ( kontextus ) def execute_test ( context : Context , x : bool , y : bool ) -> None : """ A """ kontextus értelmezőnk tesztelésére szolgáló függvény . hozzárendelni ( 'x' , x ) kontextust . hozzárendel ( 'y' , y ) kifejezés = OrExp ( # (Igaz és x) vagy (y és (nem x)) AndExp ( ConstantExp ( True ), VariableExp ( 'x' )), AndExp ( VariableExp ( 'y' )) , NotExp ( VariableExp ( 'x' ))) ) print ( kifejezés . értékel ( kontextus )) if __name__ == '__main__' : print ( 'OUTPUT:' ) context = Context () execute_test ( kontextus , igaz , hamis ) execute_test ( kontextus , hamis , igaz ) execute_test ( kontextus , hamis , hamis ) ''' KIMENET: Igaz Igaz Hamis '''

PHP

PHP forráskód <?php /** * Példa értelmező mintára összetétel használatával */ abstract class Kifejezés { privát statikus $_count = 0 ; privát $_kulcs = null ; public absztrakt függvény értelmez ( InterpreterContext $context ); public function getKey () { if ( ! isset ( $this -> _key ) ) { self :: $_count ++ ; $this -> _key = self :: $_count ; } return $this -> _key ; } } class LiteralExpression kiterjeszti a kifejezést { privát $_érték = null ; public function __construct ( $érték ) { $this -> _value = $érték ; } public function interpret ( InterpreterContext $context ) { $context -> csere ( $this , $this -> _value ); } } class VariableExpression kiterjeszti a kifejezést { privát $_név = null ; private $_val = null ; public function __construct ( $name , $val = null ) { $this -> _name = $name ; $this -> _val = $val ; } public function interpret ( InterpreterContext $context ) { if ( ! is_null ( $this -> _val ) ) $context -> csere ( $this , $this -> _val ); } public function setValue ( $érték ) { $this -> _val = $érték ; } public function getKey () { return $this -> _name ; } } abstract class OperatorExpression extends kifejezés { védett $leftoperand = null ; védett $rightoperand = null ; public function __construct ( Kifejezés $baloperand , Kifejezés $jobboperand ) { $this -> leftoperand = $baloperand ; $this -> rightoperand = $jobboperandus ; } public function interpret ( InterpreterContext $context ) { $this -> leftoperand -> interpret ( $context ); $this -> rightoperand -> interpret ( $context ); $resultleft = $kontextus -> keresés ( $this -> leftoperand ); $resultright = $kontextus -> keresés ( $this -> rightoperand ); $this -> doInterpret ( $context , $ resultleft , $resultright ); } védett absztrakt függvény doInterpret ( InterpreterContext $context , $ resultleft , $resultright ); } class EqualsExpression kiterjeszti az OperatorExpression { protected function doInterpret ( InterpreterContext $context , $ resultleft , $resultright ) { $kontextus -> csere ( $this , $ resultleft == $resultright ); } } class BooleanOrExpression kiterjeszti az OperatorExpression { protected function doInterpret ( InterpreterContext $context , $ resultleft , $resultright ) { $kontextus -> csere ( $this , $ resultleft || $resultright ); } } class BooleanAndExpression kiterjeszti az OperatorExpression { protected function doInterpret ( InterpreterContext $context , $ resultleft , $resultright ) { $context -> csere ( $this , $ resultleft && $resultright ); } } class InterpreterContext { private $_expressionstore = tömb (); public function csere ( Kifejezés $exp , $érték ) { $this -> _expressionstore [ $exp -> getKey ()] = $érték ; } public function lookup ( $exp kifejezés ) { return $this -> _expressionstore [ $exp -> getKey ()]; } } $kontextus = new InterpreterContext (); $input = new VariableExpression ( 'input' ); $statement = new BooleanOrExpression ( new EqualsExpression ( $input , new LiteralExpression ( "négy" ) ), new EqualsExpression ( $input , new LiteralExpression ( "4" ) ) ); foreach ( array ( "négy" , "4" , "52" ) ​​as $value ) { $input -> setValue ( $value ); print " { $value } :<br>" ; $nyilatkozat -> interpret ( $kontextus ); nyomtatás $context -> lookup ( $statement ) ? "Meets<br><br>" : "Nem egyezik<br><br>" ; } ?>

Lásd még