大话设计模式之装饰模式

   版权声明:本文为博主原创文章,转载需注明出处。    

    经过了前面的设计原则和工厂三姐妹、单例设计模式的学习,我相信大家已经掌握了基本的学习方法,今天我们来总结装饰模式,首先来看一下装饰模式的UML图:

                     

    接着我们根据UML图写一下源码实现:

    

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

        @Override
        public void Operation()
        {
            System.out.println("The orinal operation");
        }
        
    }
    public class Decorator extends Component{
        protected Component component;
        public void SetComponent(Component component){
            this.component = component;
        }

        @Override
        public void Operation()
        {
            if(component !=null){
                component.Operation();  //super operation
            }
        }
        
    }
    public class ConcreteDecoratorA extends Decorator{
        private String addedState ;//
        @Override
        public void Operation()
        {
            super.Operation();
            addedState = "The new decorator field";
            System.out.println("decorator new field");
        }
        
    }
    public class ConcreteDecoratorB extends Decorator{
        private void AddedBehavior(){
            System.out.println("decorator new method");
        }
        @Override
        public void Operation()
        {
            super.Operation();
            AddedBehavior();
        }
    }

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

public void main(String[] args){
        ConcreteComponent c = new ConcreteComponent();
        ConcreteDecoratorA d1 = new ConcreteDecoratorA();
        ConcreteDecoratorB d2 = new ConcreteDecoratorB();
        d1.SetComponent(c);
        d2.SetComponent(d1);
        d2.Operation();
    }

    原本的类C,我们首先使用d1对其进行装饰,然后使用d2去装饰d1,实现效果就是在c的基础上添加了新的字段和一个新的方法。   

    好了,上面就是装饰模式的源码了,可能有些晦涩了,接下来我们使用一个生活中的小例子去解释一下装饰模式。

    我们每天早上吃早饭都吃什么呢?像我的最爱就是煎饼了,接下来,我们就以煎饼为例子来解释一下装饰模式。煎饼真是无欲则钢有容乃大,我们可以在原味煎饼的基础上去加烤肠、辣条、生菜、鸡柳等。那么我们试着用装饰模式试着去描述一下这个过程吧:

   

abstract class Jianbing{
        public abstract void Operation();
    }
    //原味煎饼
    public class Yuanweijianbing extends Jianbing{

        @Override
        public void Operation()
        {
            System.out.println("原味煎饼");
        }
        
    }
   //加料煎饼
    public class Jialiaojianbing extends Jianbing{
        protected Jianbing jianbing;
        public void SetComponent(Jianbing jianbing){
            this.jianbing = jianbing;
        }

        @Override
        public void Operation()
        {
            if(jianbing !=null){
                jianbing.Operation();  
            }
        }
        
    }
    //加香肠的煎饼
    public class Xiangchang extends Jialiaojianbing{
        private void AddedBehavior(){
            System.out.println("加香肠");
        }
        @Override
        public void Operation()
        {
            super.Operation();
            AddedBehavior();
        }
        
    }
    //加辣条煎饼
    public class Latiao extends Jialiaojianbing{
        private void AddedBehavior(){
            System.out.println("加辣条");
        }
        @Override
        public void Operation()
        {
            super.Operation();
            AddedBehavior();
        }
    }
    public void main(String[] args){
        Yuanweijianbing j = new Yuanweijianbing();
        Xiangchang d1 = new Xiangchang();
        Latiao d2 = new Latiao();
        d1.SetComponent(j);
        d2.SetComponent(d1);
        d2.Operation();
    }

    这样无论你想吃什么样的煎饼,装饰器模式都能帮你做到,先后顺序由你来定。老板,来一份加肠加辣条的煎饼。九块不谢!

    装饰模式是为已有功能动态地添加更多功能的一种方式。当系统需要新功能的时候,比如在主类中假如新的字段,新的方法和新的逻辑,从而增加主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要,装饰模式提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它索要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择的、按顺序地使用装饰功能包装对象了。这样做的好处就是有效地把类的核心职责和装饰功能区分开。而且可以去除相关类中重复的装饰逻辑。其实装饰类就是在原有类基础上的加强或者说是多穿了一层。java IO 流中装饰设计模式是非常常见的,大家可以自行去查看源码体会。

    


    

    

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值