Dekoratør (design sjef)

Denne artikkelen kan inneholde upubliserte arbeider eller ubekreftede uttalelser (oktober 2014).

Du kan hjelpe ved å legge til referanser eller fjerne upublisert innhold. Se samtalesiden for mer informasjon.

I programvareteknikk er en dekoratør navnet på en av designmønsterstrukturene .

En dekoratør gjør det mulig å feste nytt ansvar dynamisk til et objekt . Dekoratører tilbyr et fleksibelt nok alternativ til arv til å komponere ny funksjonalitet.

Oversikt

Dekoratormønsteret er et av tjuetre GOF-mønstre . Det løser følgende problemer:

Når du bruker arv, utvider forskjellige underklasser en overordnet klasse på forskjellige måter. Men en utvidelse er knyttet til klassen ved kompileringstidspunktet, og kan ikke endres på kjøretid.

Java-eksempel

// ______________________________________________________________________ // Déclarations public interface IVehicule { public String getNom(); public String getMarque(); public int getPrix(); public int getPoids(); } public abstract class Voiture implements IVehicule { private String aNom; private String aMarque; protected void setNom(String pNom) { this.aNom = pNom; } public String getNom() { return this.aNom; } protected void setMarque(String pMarque) { this.aMarque = pMarque; } public String getMarque() { return this.aMarque; } } public class DS extends Voiture { public DS() { this.setNom("DS"); this.setMarque("Citroën"); } public int getPrix() { return 30000; } public int getPoids() { return 1500; } } // ______________________________________________________________________ // Décorateurs public abstract class VoitureAvecOption extends Voiture { private IVehicule aVehicule; protected void setVehicule(IVehicule pVehicule) { this.aVehicule = pVehicule; } public IVehicule getVehicule() { return this.aVehicule; } } class VoitureAvecToitOuvrant extends VoitureAvecOption { public int getPrix() { return this.getVehicule().getPrix() + 10000; } public int getPoids() { return this.getVehicule().getPoids() + 15; } } //On garde le nom du pattern Decorator pour savoir qu'on wrap un objet class DSAvecToitOuvrantDecorator extends VoitureAvecToitOuvrant { public DSAvecToitOuvrantDecorator(DS pDS) { this.setVehicule(pDS); } } public class Main { // ______________________________________________________________________ // Implémentation public static void main(String[] args) { DS vDS = new DS(); IVehicule vDSOption = new DSAvecToitOuvrantDecorator(vDS); System.out.println(vDSOption.getPoids() + " - " + vDSOption.getPrix()); } }


Eksempel i C #

Her brukes arv.

//______________________________________________________________________ // Déclarations abstract class Voiture { public abstract double Prix { get; } } class AstonMartin : Voiture { public override double Prix { get { return 999.99; } } } //______________________________________________________________________ // Décorateurs class Option : Voiture { protected Voiture _originale; protected double _tarifOption; public Option(Voiture originale, double tarif) { _originale = originale; _tarifOption = tarif; } public override double Prix { get { return _originale.Prix + _tarifOption; } } } class VoitureAvecClimatisation : Option { public VoitureAvecClimatisation (Voiture originale) : base(originale, 1.0) { } } class VoitureAvecParachute : Option { public VoitureAvecParachute (Voiture originale) : base(originale, 10.0) { } } class VoitureAmphibie : Option { public VoitureAmphibie (Voiture originale) : base(originale, 100.0) { } } //______________________________________________________________________ // Implémentation class Program { static void Main() { Voiture astonMartin= new AstonMartin(); astonMartin = new VoitureAvecClimatisation(astonMartin); astonMartin = new VoitureAvecParachute(astonMartin); astonMartin = new VoitureAmphibie(astonMartin); Console.WriteLine(astonMartin.Prix); // affiche 1110.99 } }

Eksempel i C ++

# include <iostream> # include <memory> class IVoiture { public: virtual double prix() = 0; }; class Aston_martin : public IVoiture { public: double prix() override { return 999.99l; } }; class Option_voiture : public IVoiture { public: Option_voiture(std::unique_ptr<IVoiture> voiture, double prix_option) : voiture_(std::move(voiture)) , prix_option_(prix_option) {} double prix() override { return voiture_->prix() + prix_option_; } protected: std::unique_ptr<IVoiture> voiture_; double prix_option_; }; class Option_clim : public Option_voiture { public: Option_clim(std::unique_ptr<IVoiture> voiture) : Option_voiture(std::move(voiture), 1.0) {} }; class Option_parachute : public Option_voiture { public: Option_parachute(std::unique_ptr<IVoiture> voiture) : Option_voiture(std::move(voiture), 10.0) {} }; class Option_amphibie : public Option_voiture { public: Option_amphibie(std::unique_ptr<IVoiture> voiture) : Option_voiture(std::move(voiture), 100.0) {} }; int main() { auto voiture = std::unique_ptr<IVoiture>(std::make_unique<Aston_martin>()); voiture = std::make_unique<Option_clim>(std::move(voiture)); voiture = std::make_unique<Option_parachute>(std::move(voiture)); voiture = std::make_unique<Option_amphibie>(std::move(voiture)); std::cout << voiture->prix() << "\n"; // affiche 1110.99 return 0; }

Eksempel i PHP

<?php // Interface pour rendre un objet affichable interface Affichable { public function affiche(); } // Classe contenant un message affichable class Message implements Affichable { protected $message = ''; public function __construct($message) { $this->message = $message; } public function affiche() { echo $this->message; } } // Une classe abstraite de décoration de message affichable abstract class DecorateurDeMessage implements Affichable { protected $messageDecore = null; public function __construct(Affichable $messageDecore) { $this->messageDecore = $messageDecore; } } // Une classe pour "décorer" un message en gras class MessageEnGras extends DecorateurDeMessage { public function affiche() { echo '<strong>'; $this->messageDecore->affiche(); echo '</strong>'; } } // Une classe pour "décorer" un message en italique class MessageEnItalique extends DecorateurDeMessage { public function affiche() { echo '<em>'; $this->messageDecore->affiche(); echo '</em>'; } } // Création du message $message = new Message('le message'); // On met le message en gras et en italique $messageDecore = new MessageEnItalique( new MessageEnGras( $message ) ); // On affiche le message décoré $messageDecore->affiche(); ?>

Eksempel i Delphi

Faktisk støtter språkene Delphi og Free Pascal klassehjelpere som gjør dekoratørdesignmønsteret unødvendig .

program NoMoreDecorators; type TMyObject = class procedure WriteHello; end; TMyObjectHelper = class helper for TMyObject procedure WriteHello(const Name: string); overload; end; procedure TMyObject.WriteHello; begin writeln('Hello'); end; procedure TMyObjectHelper.WriteHello(const Name: string); begin writeln('Hello, ', Name, '!'); end; var o: TMyObject; begin o := TMyObject.Create; o.WriteHello; o.WriteHello('Jean'); o.Free; end.

kilde: Delphi GOF DesignPatterns (CodePlex)

Eksempel i Delphi unit decorator; interface type IComponent = interface ['{8021ECE2-0D60-4C96-99AA-C5A6C515DF52}'] function Operation(): String; End; TComponent = class (TInterfacedObject, IComponent) public function Operation(): String; end; TDecoratorA = class (TInterfacedObject, IComponent) private FComponent: IComponent; public function Operation(): String; constructor Create(c: IComponent); end; TDecoratorB = class (TInterfacedObject, IComponent) private FComponent: IComponent; public addedState: String; function Operation(): String; function AddedBehaviour(): String; constructor Create(c: IComponent); end; TClient = class class procedure Display(s: String; c: IComponent); end; implementation { TComponent } function TComponent.Operation: String; begin Result := 'I am walking '; end; { TDecoratorA } constructor TDecoratorA.Create(c: IComponent); begin inherited Create; Self.FComponent := c; end; function TDecoratorA.Operation: String; var s: String; begin s := Self.FComponent.Operation; s := s + 'and listening to Classic FM '; Result := s; end; { TDecoratorB } function TDecoratorB.AddedBehaviour: String; begin Result := 'and I bouth a capuccino '; end; constructor TDecoratorB.Create(c: IComponent); begin inherited Create; Self.FComponent := c; Self.addedState := 'past the coffe shop '; end; function TDecoratorB.Operation: String; var s: String; begin s := Self.FComponent.Operation; s := s + 'to school '; Result := s; end; { TClient } class procedure TClient.Display(s: String; c: IComponent); begin WriteLn(s + c.Operation); end; end. { projet } program Structural.Decorator.Pattern; {$APPTYPE CONSOLE} uses SysUtils, decorator in 'decorator.pas'; var component, decoratorA, decoratorB: IComponent; decB: TDecoratorB; begin try WriteLn('Decorator Pattern' + #10); component := TComponent.Create; try decoratorA := TDecoratorA.Create(component); decoratorB := TDecoratorB.Create(component); TClient.Display('1. Basic component : ', component); TClient.Display('2. A-Decorated  : ', decoratorA); TClient.Display('3. B-Decorated  : ', decoratorB); decoratorB := TDecoratorB.Create(decoratorA); TClient.Display('4. B-A-Decorated  : ', decoratorB); decB := TDecoratorB.Create(component); decoratorA := TDecoratorA.Create(decB); TClient.Display('5. A-B-Decorated  : ', decoratorA); WriteLn(decB.addedState + decB.AddedBehaviour); finally component.Free; end; ReadLn; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end.  

Merknader og referanser

Vedlegg

Relaterte artikler