您的位置:首页 > 其它

软件工程 - 设计模式学习之装饰模式Decorator

2009-12-08 22:22 453 查看
技术交流,DH讲解 如果我们想在不改变已有类的情况下,然后加上新的功能.
这个时候我们就可以使用装饰模式了.
惯例先看下这个设计模式的UML图.



装饰模式关键是方法重载.override.
说了这么多我们来用代码来说话. 老规矩,第一个是PHP了.
class Person{
var $name='';
function __construct($a){
$this->name=$a;
}
public function show(){
echo("this is ".$this->name."!!!\n");
}
}
//穿着的基类
class Finery extends Person{
protected $component;
public function decorator($aPerson){
$this->component=$aPerson;
}
public function show() {
if(isset($this->component))
$this->component->show();
}
}
//具体的类.
Class Tshirt extends Finery{
public function show() {
echo("My TShirt@!\n");
parent::show();
}
}
//具体类2
class Tie extends Finery{
public function show(){
echo("My Tie!!\n");
parent::show();
}
}
//Test   $p = new Person("HuangJacky");
$tshirt = new Tshirt();
$tie = new Tie();

$tshirt->decorator($p);
$tie->decorator($tshirt);
$tie->show();
我们看看输出结果吧.
My Tie!! My TShirt@! this is HuangJacky!!!

我们可以看见关键的地方:
parent::show();

接下来我们还是用Java来
class Person{
private String Name;
public Person(){
this.Name="HuangJacky";
}
public Person(String aName){
this.Name=aName;
}
public void show(){
System.out.println("my name is " + Name + "!\n");
}
}
class Finery extends Person{
protected Person cmp=null;
public void decorator(Person a){
this.cmp=a;
}
public void show(){
if(cmp!=null)
cmp.show();
}
}
class TShirt extends Finery{
public void show(){
System.out.println("My TShirt!\n");
super.show();
}
}
class Tie extends Finery{
public void show(){
System.out.println("My Tie!\n");
super.show();
}
}

class Person{ private String Name; public Person(){ this.Name="HuangJacky"; } public Person(String aName){ this.Name=aName; } public void show(){ System.out.println("my name is " + Name + "!\n"); } }
class Finery extends Person{
protected Person cmp=null;
public void decorator(Person a){
this.cmp=a;
}
public void show(){
if(cmp!=null)
cmp.show();
}
}
class TShirt extends Finery{
public void show(){
System.out.println("My TShirt!\n");
super.show();
}
}
class Tie extends Finery{
public void show(){
System.out.println("My Tie!\n");
super.show();
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("TheFiend");
TShirt t = new TShirt();
Tie T = new Tie();
t.decorator(p);
T.decorator(t);
T.show();
}
}

其实代码都是一样,只是语言不同而已.
super.show();
在C#里面我们就需要改成base.show();

最后进入Delphi Time.
Type
TPerson = Class
Private
Name: String;
Public
Constructor Create( Const AName: String );
Procedure Show( ); Virtual;
End;
TFinery = Class( TPerson )
Private
FPerson: TPerson;
Public
Procedure Show( ); Override;
Property Person: TPerson Read FPerson Write FPerson;
End;
TTShirt = Class( TFinery )
Public
Procedure Show( ); Override;
End;
TTie = Class( TFinery )
Public
Procedure Show( ); Override;
End;
{ TPerson }
Constructor TPerson.Create( Const AName: String );
Begin
Self.Name := AName;
End;
Procedure TPerson.Show;
Begin
Writeln( 'my name is ' + Name );
End;
{ TFinery }
Procedure TFinery.Show;
Begin
If Assigned( FPerson ) Then
FPerson.Show;
End;
{ TTShirt }
Procedure TTShirt.Show;
Begin
Writeln( 'My Shirt' );
Inherited;
End;
{ TTie }
Procedure TTie.Show;
Begin
Writeln( 'My Tie!' );
Inherited;
End;
测试:
Var
P: TPerson;
T: TTShirt;
I: TTie;
S: String;
Begin
P := TPerson.Create( 'HuangJacky' );
T := TTShirt.Create( '' );
I := TTie.Create( '' );
T.Person := P;
I.Person := T;
I.Show;
Readln( S );
End.
OK,Delphi也是这样的.
我们可以看到Delphi里面是一句Inherited;因为调用的是父类的同名同参数的函数 所以函数名可以省略掉.不然就要写成
Inherited show();了

总结下,装饰模式适用的情况:

在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
处理那些可以撤消的职责。
当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,
为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。
另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
就到这里,我是DH.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: