.NET乐园
一个梦想,一个行动…… (欢迎光临我的淘宝http://pipis.taobao.com,专营户外手电筒、头灯、营地灯、自行车灯)
动机:对象面临着多方面功能的扩展,使用常规的继承机制使得扩展缺乏灵活性,并且带来子类的膨胀问题。使用此模式动态地给对象增加一些额外的职责


应用:.NET中Stream的实现。

场景:ThinkPad有多个系列,比如T43,T60,除笔记本基本功能,还希望通过添加模块以支持一些扩展功能,如无线、蓝牙、指纹,并且这些扩展功能可以在用户需要的任何时候进行添加。如果把具备一种或多种扩展功能的ThinkPad视为T43和T60的更小型号,会带来型号复杂的问题。如何通过添加扩展模块提供这些扩展功能,而又不会来带型号膨胀问题?

结构

Decorator模式结构图


代码

/*
 * 被扩展对象
*/

namespace DesignPattern.Decorator
{
    
public abstract class ThinkPad
    
{
        
public abstract void Start();

        
public abstract void Shutdown();
    }


    
public class T43 : ThinkPad
    
{
        
public override void Start()
        
{
        }


        
public override void Shutdown()
        
{
        }

    }


    
public class T60 : ThinkPad
    
{
        
public override void Start()
        
{
        }


        
public override void Shutdown()
        
{
        }

    }

}

namespace DesignPattern.Decorator
{
    
public abstract class ThinkPadExtension : ThinkPad
    
{
        
private ThinkPad thinkPad;

        
public ThinkPadExtension(ThinkPad thinkPad)
        
{
            
this.thinkPad = thinkPad;
        }


        
public override void Start()
        
{
            thinkPad.Start();
        }


        
public override void Shutdown()
        
{
            thinkPad.Shutdown();
        }

    }


    
public class WirelessExtension : ThinkPadExtension
    
{
        
public WirelessExtension(ThinkPad thinkPad)
            : 
base(thinkPad)
        
{
        }


        
public override void Start()
        
{
            
base.Start();

            
// 启动无线模块
        }


        
public override void Shutdown()
        
{
            
// 关闭无线模块

            
base.Shutdown();
        }

    }


    
public class BlueteethExtension : ThinkPadExtension
    
{
        
public BlueteethExtension(ThinkPad thinkPad)
            : 
base(thinkPad)
        
{
        }


        
public override void Start()
        
{
            
base.Start();

            
// 启动蓝牙模块
        }


        
public override void Shutdown()
        
{
            
// 关闭蓝牙模块

            
base.Shutdown();
        }

    }


    
public class FingerprintExtension : ThinkPadExtension
    
{
        
public FingerprintExtension(ThinkPad thinkPad)
            : 
base(thinkPad)
        
{
        }


        
public override void Start()
        
{
            
base.Start();

            
// 启动指纹模块
        }


        
public override void Shutdown()
        
{
            
// 关闭指纹模块

            
base.Shutdown();
        }

    }

}

/*
 * 客户程序
*/

namespace DesignPattern.Decorator
{
    
public class ThinkPadAssembly
    
{
        
public ThinkPad GetThinkPad()
        
{
            T60 t60 
= new T60();

            
// 具备无线功能的T60
            WirelessExtension wirelessT60 = new WirelessExtension(t60);

            
// 具备无线、蓝牙功能的T60
            BlueteethExtension blueteethT60 = new BlueteethExtension(wirelessT60);

            
// 具备无线、蓝牙、指纹功能的T60
            FingerprintExtension fingerprintT60 = new FingerprintExtension(blueteethT60);

            
return fingerprintT60;
        }

    }

}


要点
1、通过采用组合,而非继承的方法,本模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的“灵活性差”和“子类膨胀”问题。
2、接口一致。装饰对象的接口和被装饰对象的接口一致。Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。可以使用一个或多个Decorator对象来装饰一个Component对象,且装饰后的对象仍然是一个Component对象。
3、保持Component类的简单性。Component类在本模式中充当抽象接口的角色,不应该去实现具体的行为,它应集中于定义接口而不是存储数据。对数据表示的定义应延迟到子类中,否则Component类过于庞大和复杂,因而难以大量使用。而且Decorator类对于Component类应该透明——Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。
4、本模式并非解决“多子类衍生的多继承”问题,应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。
posted on 2007-06-11 14:09  Charly  阅读(474)  评论(0编辑  收藏  举报