Vierailija (suunnittelukuvio)
Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 4. tammikuuta 2016 tarkistetusta
versiosta . tarkastukset vaativat
26 muokkausta .
Vierailija |
---|
Vierailija |
Tyyppi |
käyttäytymiseen |
Tarkoitus |
muuttamatta pääluokkaa , lisää siihen uusia toimintoja. |
Rakenne |
|
Pätee tapauksissa |
kun on tarpeen suorittaa samanlainen (sama) toiminto useille luokille. |
Plussat |
- uusia toimintoja lisätään useisiin luokkiin kerralla muuttamatta näiden luokkien koodia ;
- antaa sinun saada tietoa kohteen tyypistä;
- kaksinkertainen aikataulutus;
- mahdollisuus kuvata oma algoritmi jokaiselle objektityypille .
|
Miinukset |
- kun vaihdat huollettua luokkaa, sinun on vaihdettava mallikoodi;
- uusia luokkia on vaikea lisätä, koska vierailijan ja hänen poikiensa hierarkia on päivitettävä.
|
Kuvattu suunnittelukuvioissa |
Joo |
Vierailija on käyttäytymismalli , joka kuvaa toimintoa, joka suoritetaan muiden luokkien kohteille . Kun vaihdat vierailijaa, palveluluokkia ei tarvitse muuttaa .
Malli esittelee klassisen menetelmän kadonneiden tietojen palauttamiseksi turvautumatta kaksoislähetykseen
alaspäin .
Ongelma ratkaistu
Sinun on suoritettava erillisiä toimintoja useille objekteille, mutta sinun on vältettävä saastumasta niiden koodia. Eikä ole mitään keinoa tai halua tiedustella kunkin solmun tyyppiä ja heittää osoitinta oikeaan tyyppiin ennen halutun toiminnon suorittamista.
Haaste
Jokaiselle jonkin rakenteen objektille suoritetaan yksi tai useampi toiminto. Sinun on määritettävä uusi operaatio muuttamatta objektiluokkia.
Ratkaisu
Itsenäisyyttä varten vierailijalla on erillinen hierarkia. Rakenteilla on tietty vuorovaikutusrajapinta.
Käyttö
Jos on mahdollista, että huolletun luokan hierarkia muuttuu tai se on epävakaa tai julkinen käyttöliittymä on riittävän tehokas mallille pääsyyn, sen käyttö on haitallista.
Perusluokka luodaan Visitormenetelmillä visit()jokaiselle ylätason alaluokalle Element. Lisää menetelmä accept(visitor)elementtihierarkiaan. ElementJohda Visitorluokka jokaiselle kohteelle suoritettavalle toiminnolle . Metoditoteutuksissa visit()on käytettävä luokan julkista käyttöliittymää Element. Tuloksena: asiakkaat luovat objekteja Visitorja välittävät ne jokaiselle objektille Elementkutsumalla accept().
Suositukset
Mallia tulee käyttää, jos:
- on olemassa useita eri luokkiin kuuluvia objekteja, joilla on erilaiset rajapinnat, mutta niille on suoritettava toimintoja, jotka riippuvat tietyistä luokista;
- rakenteelle on tarpeen suorittaa erilaisia toimintoja, jotka monimutkaistavat rakennetta;
- rakenteeseen lisätään usein uusia operaatioita.
Edut ja haitat
Edut :
- yksinkertaistaa uusien toimintojen lisäämistä;
- liittoon liittyvien toimintojen luokassa Visitor;
- luokka Visitorvoi muistaa jonkin tilan itsessään kulkiessaan kontin läpi.
Haitat :
- uusia luokkia on vaikea lisätä, koska vierailijan ja hänen poikiensa hierarkia on päivitettävä.
Toteutus
- Lisää menetelmä accept(Visitor)elementtihierarkiaan.
- Luo perusluokka Visitorja määritä menetelmät visit()kullekin elementtityypille.
- Luo johdetut luokat Visitorjokaiselle elementeille suoritettavalle toiminnolle.
- Asiakas luo objektin Visitorja välittää sen kutsutulle menetelmälleaccept().
Toteutusesimerkki
C++ :ssa
#include <iostream>
#sisällytä <merkkijono>
luokka Foo ;
luokka Baari ;
luokka Bas ;
luokan vierailija {
julkinen :
virtuaalinen tyhjäkäynti ( Foo & ref ) = 0 ; _
virtuaalinen tyhjäkäynti ( Bar & ref ) = 0 ; _
virtuaalinen tyhjäkäynti ( Baz & ref ) = 0 ; _
virtuaalinen ~ Vierailija () = oletus ;
};
class element {
julkinen :
virtuaalinen void hyväksyä ( Vierailija & v ) = 0 ;
virtuaalinen ~ Elementti () = oletus ;
};
luokka Foo : julkinen elementti {
julkinen :
void hyväksy ( Vierailija & v ) ohitus {
v . vierailla ( * tämä );
}
};
luokkapalkki : julkinen elementti { _
julkinen :
void hyväksy ( Vierailija & v ) ohitus {
v . vierailla ( * tämä );
}
};
luokka Baz : julkinen elementti {
julkinen :
void hyväksy ( Vierailija & v ) ohitus {
v . vierailla ( * tämä );
}
};
luokka GetType : julkinen Vierailija {
julkinen :
std :: merkkijonoarvo ; _
julkinen :
void visit ( Foo & ref ) override {
arvo = "foo" ;
}
void visit ( Bar & ref ) override {
arvo = "palkki" ;
}
void visit ( Baz & ref ) override {
arvo = "perus" ;
}
};
int main () {
Foo foo ;
baari baari ;
baz baz ;
Elementti * elementit [] = { & foo , & bar , & baz };
for ( auto elem : elements ) {
GetType vierailija ;
elem -> hyväksy ( vierailija );
std :: cout << vierailija . arvo << std :: endl ;
}
paluu 0 ;
}
Java- toteutusesimerkki
public class Demo {
public static void main ( String [ ] args ) {
Piste p = new Point2d ( 1 , 2 );
Vierailija v = uusi Chebyshev ();
p . hyväksy ( v );
Järjestelmä . ulos . println ( s . getMetric () );
}
}
käyttöliittymä Vierailija {
public void visit ( Point2d p );
julkinen mitätön vierailu ( Point3d p );
}
abstrakti luokka Piste {
julkinen abstrakti void hyväksyä ( Vierailija v );
yksityinen kaksoismetriikka = -1 ; _ _ public double getMetric ( ) { paluumittari ; } public void setMetric ( kaksoismetriikka ) { this . _ metriikka = metriikka ; } }
luokka Piste2d laajentaa pistettä {
public Piste2d ( double x , double y ) {
this . x = x ;
tämä . y = y_ _
}
public void hyväksyä ( Vierailija v ) {
v . vierailla ( tämä );
}
yksityinen double x ;
public double getX () { return x ; }
yksityinen double y ;
public double getY () { return y ; }
}
luokka Piste3d laajentaa pistettä {
public Piste3d ( double x , double y , double z ) {
this . x = x ;
tämä . y = y_ _
tämä . z = z _
}
public void hyväksyä ( Vierailija v ) {
v . vierailla ( tämä );
}
yksityinen double x ;
public double getX () { return x ; }
yksityinen double y ;
public double getY () { return y ; }
yksityinen kaksinkertainen z ;
julkinen double getZ () { return z ; }
}
luokka Euclid toteuttaa Visitor {
public void visit ( Point2d p ) {
p . setMetric ( Math . sqrt ( p . getX () * p . getX () + p . getY ( ) * p . getY ( ) ) );
}
julkinen mitätön vierailu ( Point3d p ) {
p . setMetric ( Math . sqrt ( p . getX () * p . getX () + p . getY ( ) * p . getY ( ) + p . getZ () * p . getZ () ) );
}
}
luokka Chebyshev toteuttaa Vierailija {
julkinen void käynti ( Point2d p ) {
double ax = matematiikka . abs ( p.getX ( ) ) ; double -ay = Matematiikka . abs ( s . getY () ); p . setMetric ( ax > ay ? ax : ay ); } julkinen void -käynti ( Piste3d p ) { kaksoiskirves = Math . _ abs ( p.getX ( ) ) ; double -ay = Matematiikka . abs ( s . getY () ); double az = Matematiikka . abs ( s . getZ () ); double max = ax > ay ? kirves : ay ; if ( max < az ) max = az ; p . setMetric ( max ); } }
Toteutusesimerkki
C# :ssa
julkinen staattinen luokka Demo
{
yksityinen staattinen void Pää ()
{
Piste p = uusi Piste2D ( 1 , 2 );
IVisitor v = uusi Chebyshev ();
p . hyväksy ( v );
konsoli . WriteLine ( s . Metric );
}
}
sisäinen käyttöliittymä IVisitor
{
void Visit ( Point2D p );
void Visit ( Point3Dp ) ;
}
sisäinen abstrakti luokka Piste
{
julkinen double Metric { get ; asettaa ; } = -1 ; _ julkinen abstrakti void Hyväksy ( IVisitor vierailija ); }
sisäinen luokka Piste2D : Piste
{
public Piste2D ( double x , double y )
{
X = x ;
Y = y_ _
}
public double X { get ; }
julkinen double Y { get ; }
public override void Hyväksy ( IVisitor vierailija )
{
vierailija . vierailla ( tämä );
}
}
sisäinen luokka Piste3D : Piste
{
public Point3D ( double x , double y , double z )
{
X = x ;
Y = y_ _
Z = z _
}
public double X { get ; }
julkinen double Y { get ; }
julkinen double Z { get ; }
public override void Hyväksy ( IVisitor vierailija )
{
vierailija . vierailla ( tämä );
}
}
sisäinen luokka Euclid : IVisitor
{
public void Vierailu ( Point2D p )
{
p . Metric = matematiikka . Sqrt ( p . X * p . X + p . Y * p . Y );
}
public void Vierailu ( Point3D p )
{
p . Metric = matematiikka . Sqrt ( p . X * p . X + p . Y * p . Y + p . Z * p . Z );
}
}
sisäinen luokka Chebyshev : IVisitor
{
public void Vierailu ( Piste2D p )
{
var ax = Math . abs ( s . X );
varay = matematiikka . _ Abs ( s . Y ); p . Metrinen = ax > ay ? kirves : ay ; }
public void Vierailu ( Piste3D p )
{
var ax = Math . abs ( s . X );
varay = matematiikka . _ Abs ( s . Y ); var az = Math . Abs ( s . Z ); varmax = ax > ay ? _ kirves : ay ; if ( max < az ) max = az ; p . Metrinen = max ; } }
Esimerkki toteutuksesta
php :ssä
<?php
käyttöliittymä Vierailija {
julkinen toimintokäynti ( Point $point ) ; }
abstrakti class Piste {
julkinen abstrakti funktio hyväksyä ( Vierailija $vierailija );
yksityinen $_metriikka = - 1 ;
public function getMetric () {
return $this -> _metric ;
}
julkinen funktio setMetric ( $metriikka ) {
$this -> _metric = $metriikka ;
}
}
luokka Piste2d laajentaa pistettä {
julkinen funktio __konstrukti ( $x , $y ) {
$this -> _x = $x ;
$this -> _y = $y ;
}
public function hyväksyä ( Vierailija $vierailija ) {
$vierailija -> vierailu ( $this );
}
yksityinen $_x ;
julkinen funktio getX () { return $this -> _x ; }
yksityinen $_y ;
julkinen funktio getY () { return $this -> _y ; }
}
luokka Piste3d laajentaa pisteen {
julkinen funktio __konstrukti ( $x , $y , $z ) {
$this -> _x = $x ;
$this -> _y = $y ;
$this -> _z = $z ;
}
public function hyväksyä ( Vierailija $vierailija ) {
$vierailija -> vierailu ( $this );
}
yksityinen $_x ;
julkinen funktio getX () { return $this -> _x ; }
yksityinen $_y ;
julkinen funktio getY () { return $this -> _y ; }
yksityinen $_z ;
julkinen funktio getZ () { return $this -> _z ; }
}
luokka Euclid toteuttaa Vierailijan {
julkinen toimintokäynti ( Piste $p ) { if ( $p instanceof Point2d ) $p -> setMetric ( sqrt ( $p -> getX () * $p -> getX () + $p - > getY ) () * $p -> getY () ) ); elseif ( $p instanceof Point3d ) $p -> setMetric ( sqrt ( $p -> getX () * $p -> getX () + $p - > getY ( ) * $ p - > getY ( ) + $p - > getZ () * $p -> getZ () ) ); } }
luokka Chebyshev toteuttaa Vierailija {
julkinen toiminto vierailu ( Piste $p ) {
if ( $p instanceof Point2d ){
$ax = abs ( $p -> getX () );
$ay = abs ( $p -> getY () );
$p -> setMetric ( $ax > $ay ? $ax : $ay );
}
elseif ( $p instanceof Point3d ){
$ax = abs ( $p -> getX () );
$ay = abs ( $p -> getY () );
$az = abs ( $p -> getZ () );
$max = $ax > $ay ? $ax : $ay ;
if ( $max < $az ) $max = $az ;
$p -> setMetric ( $max );
}
}
}
funktion aloitus (){
$p = new Piste2d ( 1 , 2 );
$v = uusi Chebyshev ( );
$p -> hyväksy ( $v );
echo ( $p -> getMetric () );
};
aloita ();
Toteutusesimerkki
Pythonissa
from abc import ABCMeta , abstrakti
menetelmä kirjoittamisesta Import List
luokan vakooja ( metaclass = ABCMeta ):
"""
Vakoojavierailija
"""
@abstractmethod
def visit_military_base ( self , military_base : 'MilitaryBase' ) -> Ei mitään :
"""
Vieraile laivaston sotilastukikohdassa
""
"
@abstractmethod
def visit_headquarters ( self , headquarters : 'Headquarters' ) -> Ei mitään :
"""
Vieraile armeijan esikunnassa
"""
-passi
luokka MilitaryFacility ( metaclass = ABCMeta ):
"""
Sotilaslaitos - vierailtu laitos
"""
@abstractmethod
def hyväksy ( itse , vakooja : vakooja ) -> Ei mitään :
"""
Hyväksy vakoojavierailija
"""
pass
luokan sotilastukikohta ( MilitaryFacility ):
"""
Sukellusveneen sotilastukikohta
"""
def __init__ ( itse ) -> Ei mitään :
itse . _secret_draftings = 1
itse . _ydinsukellusveneet = 1
def __repr__ ( self ) -> str :
return 'Sotilasalueella on {} ydinsukellusvenettä ja {} salaisia suunnitelmia' . muoto (
itse . _ydinsukellusveneet , itse . _salaiset_luonnokset
)
def hyväksy ( itse , vakooja : Vakooja ) -> Ei mitään :
vakooja . visit_military_base ( itse )
def remove_secret_draftings ( itse ) -> Ei mitään :
jos itse . _secret_draftings :
itse . _salaiset_luonnokset -= 1
def remove_nuclear_submarine ( itse ) -> Ei mitään :
jos itse . _nuclear_submarines :
itse . _ydinsukellusveneet -= 1
@property
def is_combat_ready ( itse ) -> bool :
palauttaa itsensä . _ydinsukellusveneet > 0
luokan päämaja ( MilitaryFacility ):
"""
Armeijan esikunta
"""
def __init__ ( itse ) -> Ei mitään :
itse . _generals = 3
itse . _secret_documents = 2
def __repr__ ( itse ) -> str :
return ' Päämajassa on {} kenraalia ja {} salaista asiakirjaa ' . muoto (
itse . _generals , self . _secret_documents
)
def hyväksy ( itse , vakooja : Vakooja ) -> Ei mitään :
vakooja . visit_headquarters ( itse )
def remove_general ( itse ) -> Ei mitään :
jos itse . _kenraalit :
itse . _kenraalit -= 1
def remove_secret_documents ( itse ) -> Ei mitään :
jos itse . _secret_documents :
itse . _salaiset_asiakirjat -= 1
@property
def is_command_ready ( itse ) -> bool :
palauttaa itsensä . _yleiset > 0
luokka ScoutSpy ( Spy ):
"""
Scout (konkreettinen vakooja)
"""
def __init__ ( itse ):
itse . _collected_info = {}
# Täällä tiedämme jo tietyn objektityypin
def visit_military_base ( self , military_base : MilitaryBase ) -> None :
self . _collected_info [ 'base' ] = 'Sotilastukikohta: \n\t {} \n\t Valmis: {} ' . muoto (
str ( sotilaallinen_tukikohta ),
'Kyllä' , jos sotilaallinen_tukikohta . is_combat_ready muuten 'Ei'
)
def visit_headquarters ( itse , pääkonttori : Headquarters ) -> Ei mitään :
itse . _collected_info [ 'headquarters' ] = 'Päämaja: \n\t {} \n\t Komento: {} ' . muoto (
str ( headquarters ),
'Käynnissä' , jos päämaja . is_command_ready else 'Ei käytössä'
)
def report ( self ) -> str :
return 'Tietoja tiedustelulta: \n {} \n ' . muoto (
' \n ' . join ( itse . _collected_info . arvot ( )
)
luokan JamesBond ( Spy ):
"""
James Bond (toinen tietty vakooja)
"""
def visit_military_base ( itse , sotilastukikohta : MilitaryBase ) -> Ei mitään :
# James Bond vierailee sotilastukikohdassa
military_base . remove_secret_draftings () # varastaa armeijan tukikohdan salaiset piirustukset
. remove_nuclear_submarine () # ja lopulta räjäyttää ydinsukellusveneen
def visit_headquarters ( itse , pääkonttori : Headquarters ) -> Ei mitään :
# James Bond vierailee
päämajassa . remove_general () # ...
päämaja . remove_general () # ...
päämaja . remove_secret_documents () # ...
pääkonttori . remove_general () # Tuhoaa kaikki kenraalit peräkkäin
päämaja . remove_secret_documents () # ja varastaa kaikki salaiset asiakirjat
if __name__ == '__main__' :
tukikohta = Sotilastukikohta ()
hq = Esikunta ()
# Riippumatta siitä mitkä MilitaryFacility
-tilat = [ base , hq ] # type: List[MilitaryFacility]
scout = ScoutSpy ()
print ( ' Sending a scout... \n ' )
for f tiloissa : f . hyväksyä ( tiedustelija )
tulosta ( scout.report ( ) )
print ( 'Sending Bond on a mission... \n ' )
spy = JamesBond (
) for f tiloissa : f . hyväksyä ( vakooja )
print ( 'Lähetetään partio päivittääkseen tietoja... \n ' )
for f in tiloissa :
f . hyväksyä ( tiedustelija )
tulosta ( scout.report ( ) )
"""
OUTPUT:
Lähetetään tiedustelija...
Tietoa tiedustelulta: Keskusesikunta:
Esikunnassa
on 3 kenraalia ja 2 salaista asiakirjaa
Komento: Toimiva
Sotilastukikohta: Sotilastukikohdassa
on 1 ydinsukellusvene ja 1 salainen piirros
Taisteluvalmius: Kyllä
Bondin lähettäminen lähetystyöhön...
Lähetetään tiedustelijaa päivittämään tiedot...
Tietoja tiedustelulta: Keskusesikunta:
Esikunnassa
on 0 kenraalia ja 0 salaista asiakirjaa
Komento: Ei toimi
Sotilastukikohta: Sotilastukikohdassa
on 0 ydinsukellusvenettä ja 0 salaisia piirustuksia
Valmius: Ei yhtään
"""
Toteutusesimerkki
Delphissä
ohjelma Demo ;
tyyppi
Point2D = luokka ;
Piste3D = luokka ;
IVisitor = käyttöliittymämenettely
Visit ( p : Point2D ) ; _ ylikuormitus ; menettely Vierailu ( p : Point3D ) ; ylikuormitus ; loppu ;
Piste = luokka
yksityinen
FMetric : Double ;
julkinen
omaisuus Metric : Kaksoislue FMetric kirjoittaa FMetric ; _ menettely Hyväksy ( vierailija : IVisitor ) ; virtuaalinen ; abstrakti ; loppu ;
Piste2D = luokka ( Piste )
yksityinen
FX : Double ;
FY : Double ;
julkinen
omaisuus X : Double read FX ;
ominaisuus Y : Kaksoislue FY ; _
rakentaja Luo ( const x , y : Double ) ;
menettely Hyväksy ( Vierailija : IVisitor ) ; ohittaa ;
loppu ;
Point3D = luokka ( Piste )
yksityinen
FX : Double ;
FY : Double ;
FZ : Double ;
julkinen
omaisuus X : Double read FX ;
ominaisuus Y : Kaksoislue FY ; _ ominaisuus Z : Double read FZ ;
konstruktori Luo ( const x , y , z : Double ) ;
menettely Hyväksy ( Vierailija : IVisitor ) ; ohittaa ;
loppu ;
Euklid = luokka ( TInterfacedObject , IVisitor )
julkinen
menettely Visit ( p : Point2D ) ; ylikuormitus ;
menettely Vierailu ( p : Point3D ) ; ylikuormitus ;
loppu ;
Chebyshev = luokka ( TInterfacedObject , IVisitor )
julkinen
menettely Visit ( p : Point2D ) ; ylikuormitus ;
menettely Vierailu ( p : Point3D ) ; ylikuormitus ;
loppu ;
{Piste2D}
menettely Piste2D . Hyväksy ( Vierailija : IVisitor ) ;
aloita
Vierailija . Vieraile ( itse ) ;
loppu ;
rakentaja Point2D . Luo ( const x , y : Double ) ;
alkaa
FX := x ;
FY := y ;
loppu ;
{Point3D}
menettely Point3D . Hyväksy ( Vierailija : IVisitor ) ;
aloita
Vierailija . Vieraile ( itse ) ;
loppu ;
rakentaja Point3D . Luo ( const x , y , z : Double ) ;
alkaa
FX := x ;
FY := y ;
FX := z ;
loppu ;
{ Euclid }
menettely Eulid . Vierailu ( p : Point2D ) ;
aloita
p . Metriikka := Sqrt ( Sqr ( p . X ) + Sqr ( p . Y )) ;
loppu ;
menettely Eulid . Vierailu ( p : Point3D ) ;
aloita
p . Metriikka := Sqrt ( Sqr ( p . X ) + Sqr ( p . Y ) + Sqr ( p . Z )) ;
loppu ;
{Chebyshev}
menettely Chebyshev . Vierailu ( p : Point2D ) ;
var
ax , ay : Double ;
alkaa
ax := Abs ( p . X ) ;
ay := Abs ( p . Y ) ;
jos ax > ay sitten
p . Mittari := ax
else
p . Metrinen : = ay loppu ;
menettely Chebyshev . Vierailu ( p : Point3D ) ;
var
ax , ay , az , max : Double ;
alkaa
ax := Abs ( p . X ) ;
ay := Abs ( p . Y ) ;
az := Abs ( p . Z ) ;
jos ax > ay niin
max := ax
else
max := ay ;
jos max < az sitten
max := az ;
p . Mittari := max ;
loppu ;
varp
: piste ; _ v : IVVisitor ; alkaa p := Piste2D . Luo ( 1 , 2 ) ;
v := Chebyshev . luoda ;
p . hyväksyä ( v ) ;
WriteLn ( s . Metric : 0 : 2 ) ;
v := Eulid . luoda ;
p . hyväksyä ( v ) ;
WriteLn ( s . Metric : 0 : 2 ) ;
p . Ilmainen ;
Readln ; // odota, kunnes painat Enter
end .
Toteutusesimerkki
Swiftissä
protokolla WarehouseItem {
var name : String { get set }
var isBroken : Bool { get set }
var price : Int { get set }
}
class WarehouseItemImpl : WarehouseItem {
var nimi : String = ""
var isBroken : Bool = false
var price : Int = 0
init ( nimi : String , isBroken : Bool , hinta : Int ) {
self . nimi = nimi
itse . isBroken = isBroken
self . hinta = hinta
}
}
protokolla Warehouse {
var items : [ WarehouseItem ] { get set }
func addItem ( nimike : WarehouseItem )
func accept ( vierailija : BasicVisitor )
}
class WarehouseImpl : Varasto {
var items : [ WarehouseItem ] = []
func addItem ( tuote : WarehouseItem ) {
kohteita . liittää ( kohde )
}
func accept ( vierailija : BasicVisitor ) {
kohteissa olevalle kohteelle { vierailija . _ vierailla ( kohde nimellä AnyObject ) } } }
protokolla BasicVisitor {
func visit ( _ anObject : AnyObject )
}
class QualityCheckerVisitor : BasicVisitor {
func visit ( _ anObject : AnyObject ) {
if let obj = anObject as ? Varastotuote {
if obj . isBroken {
print ( "on Broken true" )
} else {
print ( "on Broken false" )
}
jos _ = anObject as ? _ Varasto { tulosta ( "Hyvä varasto" ) } } }
}
Class PriceCheckerVisitor : BasicVisitor {
func visit ( _ anObject : AnyObject ) {
if let obj = anObject as ? WarehouseItem {
print ( " \( obj . name ) | Hinta: \( obj . hinta ) rub." )
}
jos _ = anObject as ? _ Varasto { tulosta ( "Ei kustannuksia" ) } }
}
// Käytä Vierailijaa
anna varasto = WarehouseImpl ()
varasto . addItem ( tuote : WarehouseItemImpl ( nimi : " Nimike 1 " , isBroken : true , hinta : 100 ))
varasto . addItem ( tuote : WarehouseItemImpl ( nimi : " Nimike 2 " , isBroken : false , hinta : 300 ))
varasto . addItem ( tuote : WarehouseItemImpl ( nimi : "Tuote 3" , isBroken : false , hinta : 500 ))
anna hinta = PriceCheckerVisitor ()
anna qulity = QualityCheckerVisitor ()
varasto . hyväksy ( vierailija : hinta )
varasto . hyväksy ( vierailija : qulity )
Kirjallisuus
- E. Gamma, R. Helm, R. Johnson, J. Vlissides . Olio-suunnittelun tekniikat. Suunnittelumalleja. - Pietari. : Peter, 2001. - 368 s. — ISBN 5-272-00355-1 .
Linkit