装饰者模式 - OK

  装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

    装饰者模式隐含的是通过一条条装饰链去实现具体对象,每一条装饰链都始于一个Componet对象,每个装饰者对象后面紧跟着另一个装饰者对象,而对象链终于ConcreteComponet对象。

  用粗略的话讲:装饰模式就是为已有功能动态地添加更多功能的一种方式。

  何为动态。比如打折策略。3折后再减30元再打8折,

  UML图如下:

    

  Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰着抽象类,继承了Component从外类来扩展Component类的功能,但对于Component来说,就无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象。起到给Component添加职责的功能。

  实现代码示例:

  装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了。每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。

  示例:

复制代码
namespace 装饰者模式
{
    class Program
    {
        static void Main(string[] args)
        {
            ConcreateComponent c = new ConcreateComponent();
            ConcreteDecorator眉毛 d1 = new ConcreteDecorator眉毛();
            ConcreteDecorator头发 d2 = new ConcreteDecorator头发();

            d1.SetComponent(c);     //d1里面放入c,是为了调用原始c的 捕获素颜美女
            d2.SetComponent(d1);    //d1是画过眉毛的
            d2.Operation();

            Console.ReadKey();
        }
    }  

    abstract class Component
    {
        public abstract void Operation();
    }

    class ConcreateComponent : Component
    {
        //原始内容,具体装饰类都会调用一次
        public override void Operation()
        {
            Console.WriteLine("捕获素颜美女一个!");
        }
    }

    abstract class Decorator : Component
    {
        //里面放一个父接口
        protected Component component;

        public void SetComponent(Component component)   //设置Component
        {
            this.component = component;
        }

        public override void Operation()    //用接收到的Component的Operation方法来重写父Component接口的Operation方法
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }

    class ConcreteDecorator眉毛 : Decorator
    {
        private string addedState;      //代表画眉毛的实际操作

        public override void Operation()
        {
            base.Operation();           //素颜美女(原始内容)
            Console.WriteLine("帮美女画画眉!");
            addedState = "眉毛漂亮了!";    //实际装饰内容
        }
    }

    class ConcreteDecorator头发 : Decorator
    {
        public override void Operation()
        {
            base.Operation();           //原始内容
            Console.WriteLine("帮美女梳梳头!");
            AddedBehavior();            //实际装饰内容
        }

        private void AddedBehavior()    //本类独有的方法,以区别于ConcrateDecoratorA
        {
            Console.WriteLine("头发变精神了!");
        }
    }
}
复制代码

  这个示例写得不错,基本上掌握了装饰者的作用。

  

  装饰者模式的应用场景:

  1. 想透明并且动态地给对象增加新的职责的时候。
  2. 给对象增加的职责,在未来存在增加或减少可能。
  3. 用继承扩展功能不太现实的情况下,应该考虑用组合的方式。

  装饰者模式的优点:

  1. 通过组合而非继承的方式,实现了动态扩展对象的功能的能力。
  2. 有效避免了使用继承的方式扩展对象功能而带来的灵活性差,子类无限制扩张的问题。
  3. 充分利用了继承和组合的长处和短处,在灵活性和扩展性之间找到完美的平衡点。
  4. 装饰者和被装饰者之间虽然都是同一类型,但是它们彼此是完全独立并可以各自独立任意改变的。
  5. 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

  装饰者模式的缺点:

  1. 装饰链不能过长,否则会影响效率。
  2. 因为所有对象都是继承于Component,所以如果Component内部结构发生改变,则不可避免地影响所有子类(装饰者和被装饰者),也就是说,通过继承建立的关系总是脆弱地,如果基类改变,势必影响对象的内部,而通过组合(Decoator HAS A Component)建立的关系只会影响被装饰对象的外部特征。
  3. 只在必要的时候使用装饰者模式,否则会提高程序的复杂性,增加系统维护难度。
 
 
分类: 设计模式
 
 
 
+加关注
0
0
 
(请您对文章做出评价)
 
« 上一篇: 策略模式 - OK
» 下一篇: 代理模式 - OK
posted on 2015-09-02 11:27  铭轩同学 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/mingxuantongxue/p/4778089.html

好的,我理解你的需求是将循环中的 if 语句解耦,使用装饰者模式来实现,并将子类的执行结果保存在 List 中,最后统一调用 save 方法进行操作。那么我来给你讲解一下如何实现。 首先,我们需要定义一个超类,用于保存子类的执行结果: ```java public abstract class RecordDecorator { protected List<Record> records = new ArrayList<>(); public abstract void execute(Record record); public List<Record> getRecords() { return records; } } ``` 在该超类中,我们定义了一个 List 类型的成员变量 `records`,用于保存子类的执行结果。同时,我们定义了一个抽象方法 `execute`,用于子类的具体执行操作。 接着,我们需要定义两个子类,分别对应原来的两个 if 语句: ```java public class PTRRecordDecorator extends RecordDecorator { @Override public void execute(Record record) { if (record.getType().equalsIgnoreCase("PTR")) { records.add(record); } } } public class PRRRecordDecorator extends RecordDecorator { @Override public void execute(Record record) { if (record.getType().equalsIgnoreCase("PRR")) { records.add(record); } } } ``` 在这两个子类中,我们重写了超类的 `execute` 方法,对应原来的两个 if 语句,将符合条件的记录添加到成员变量 `records` 中。 最后,我们需要使用装饰者模式来解耦原来的循环中的 if 语句: ```java RecordDecorator ptrDecorator = new PTRRecordDecorator(); RecordDecorator prrDecorator = new PRRRecordDecorator(); for (Record record : container) { ptrDecorator.execute(record); prrDecorator.execute(record); } List<Record> ptrRecords = ptrDecorator.getRecords(); List<Record> prrRecords = prrDecorator.getRecords(); save(ptrRecords); save(prrRecords); ``` 在主函数中,我们创建了两个子类的实例,分别对应原来的两个 if 语句。然后在循环中,我们通过调用 `execute` 方法,将每个记录交给两个子类处理。最后,我们通过调用 `getRecords` 方法,获取子类处理后的结果,并分别调用 `save` 方法进行操作。 这样,我们就使用装饰者模式,将原来的循环中的 if 语句解耦,同时将子类的执行结果保存在 List 中,最后统一进行操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值