zoukankan      html  css  js  c++  java
  • C#设计模式——装饰者模式(Decorator Pattern)

    一、例子
    在软件开发中,我们往往会想要给某一类对象增加不同的功能。比如要给汽车增加ESP、天窗或者定速巡航。如果利用继承来实现,就需要定义无数的类,Car,ESPCar,CCSCar,SunRoofCar,ESPCCSCar……很容易就导致“子类爆炸”问题。
    上述“子类爆炸”问题的根源在于该解决方案利用继承来扩展功能,缺乏灵活性。那么如何能在扩展功能的同时避免“子类爆炸”呢?
    二、装饰者模式
    装饰者模式装饰者模式可以动态地给一个对象增加一些额外的职责。就增加功能来说,装饰者模式相比生成子类更为灵活。
    装饰者模式的结构图如下

    Component定义了一个接口,可以利用Decorator为实现了这个接口的对象动态地增加职责
    ConcreteComponent定义了一个实现了Component接口的对象
    Decorator是抽象装饰者类,继承自Component接口,并包含有一个实现了Component接口的对象
    ConcreteDecorator是具体装饰者类,用于为ConcreteComponent增加职责
    在以上结构中,Component和Decorator可以情况省略。
    三、实现
    下面用装饰者模式来解决前面的例子
    首先实现Car

    1 publicclass Car
    2 {
    3 publicvirtualvoid Description()
    4 {
    5 Console.WriteLine("Basic Car");
    6 }
    7 }

    接下来实现ConcreteDecorator
    ESP装饰者

     1 publicclass ESPDecorator : Car
    2 {
    3 Car _car;
    4
    5 public ESPDecorator(Car car)
    6 {
    7 _car = car;
    8 }
    9
    10 publicoverridevoid Description()
    11 {
    12 _car.Description();
    13 Console.WriteLine("Add ESP");
    14 }
    15 }

    定速巡航装饰者

     1 publicclass CCSDecorator : Car
    2 {
    3 Car _car;
    4
    5 public CCSDecorator(Car car)
    6 {
    7 _car = car;
    8 }
    9
    10 publicoverridevoid Description()
    11 {
    12 _car.Description();
    13 Console.WriteLine("Add CCS");
    14 }
    15 }

    天窗装饰者

     1 publicclass SunRoofDecorator : Car
    2 {
    3 Car _car;
    4
    5 public SunRoofDecorator(Car car)
    6 {
    7 _car = car;
    8 }
    9
    10 publicoverridevoid Description()
    11 {
    12 _car.Description();
    13 Console.WriteLine("Add SunRoof");
    14 }
    15 }

    最后看一下如何使用装饰者来给Car增加功能

    1 staticvoid Main(string[] args)
    2 {
    3 Car car =new ESPDecorator(new CCSDecorator(new SunRoofDecorator(new Car())));
    4 car.Description();
    5 Console.ReadLine();
    6 }
  • 相关阅读:
    JAVA多线程知识点
    RabbitMQ和Springboot集成RabbitMQ知识点
    JAVA动态代理cglib或jdk
    [转]解决System.Data.SqlClient.SqlException (0x80131904): Timeout 时间已到的问题的一个方向
    [转]C#判断文档编码格式,并读取文档数据(防止出现乱码)
    create_linux命令写入到sh脚本并删除
    cmd cd切换到d盘
    sql 优化前后
    LISTAGG()WITHIN GROUP()
    使用shell递归遍历文件并打印所有文件名的绝对路径
  • 原文地址:https://www.cnblogs.com/saville/p/2110830.html
Copyright © 2011-2022 走看看