Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Decorator Pattern

Part of TutorialDesignPatterns

Description

Examples of implementing the Gang of Four Decorator Pattern. You can find description on: http://en.wikipedia.org/wiki/Decorator_pattern

Example : Decorator Pattern

/* This code is written since v1.x, If you want to use this code in v2.x just add override in the toString() */

import std.stdio;
import std.string;

interface Unit { // component
	
	void attack(Player u);
	
}

interface AttackDecorator : Unit { // decorator
	// nothing to implement
}

class Player : Unit { // concrete component

	private string name;
	
	this() { }
	
	this(string name) {
		this.name = name;
	}
	
	void attack(Player u) {
		writefln("Target: " ~ u.toString());
		writef("normal attack");
	}
	
	public string getName() {
		return name;
	}
	
}

class Knight : Player {
	
	this() {
		super("Knight"); // default name
	}
	
	this(string name) {
		super(name); // call the super class' constructor
		writefln("%s has joined the game", this);
	}
	
	string toString() { // string representation of this class
		return super.getName();
	}
}

class Assassin : Player {

	this() { 
		super("Assassin"); // default name
	}
	
	this(string name) {
		super(name); // call the super class' constructor
		writefln("%s has joined the game", this);
	}
	
	string toString() { // string representation of this class
		return super.getName();
	}
	
}

class Bash : AttackDecorator {
	
	private Unit wrapperObj;
	
	this(Unit u) {
		this.wrapperObj = u;
	}
	
	void attack(Player u) {
		wrapperObj.attack(u);
		writef(" + bash");
	}
	
}

class ChainLightning : AttackDecorator {
	
	private	Unit wrapperObj;
	
	
	this(Unit u) {
		this.wrapperObj = u;
	}
	
	~this() { }
	
	void attack(Player u) {
		wrapperObj.attack(u);
		writefln(" + chain lightning");
	}
	
}

int main() {
	Unit player = new Knight("Arth"); // the attacker
	
	player = new Bash(player); // decorated attack
	player = new ChainLightning(player); // decorated attack umm... err btw does knight have a chain lightning?
	
	player.attack(new Assassin("Lloyd"));  // the target
	// hopefully assassin don't have a chance to fight back ^_^
	
	/* You can add your own code here if you want the assassin to fight back
	 * But first you need to change something in the code and add your code
	 * below this comment block
	 */
	return 0;
}