• 红草莓(餐厅)装饰者模式


        11:30超出了,哥们几个(当然还有几个女的,比如:“全总”,“鞠总”。),脚步依旧。沿着熟悉的路线,穿过那漫长的十字路口,奔着我们的食物(抽象类),当然这个抽象类包含了计算价格这个方法了getCost(),不过如果某一天红草莓发慈悲,可以我们这些劳苦大众,免费给我们吃,当然是非常愿意的啦,冲向红草莓(新型餐厅)。

        来到红草莓楼下,几位女同志比较喜欢在一楼吃那些什么砂锅,面条什么的(具体的食物,实现了食物这个抽象类的getCost()方法,因为不管怎么样,都是要收费的),介于男同胞一直以来体力消耗都比较厉害,所以那些东西基本上吃不饱,所以就到二楼吃饭。

       先来看看把,首先说女同志吧,女同志特别爱挑剔,吃个砂锅,要往里面加入一些配料,比如说,金针菇啊,海带啊,油豆腐啊,豆腐干啊,反正很多,跟每个人的口味有关。

    好吧,那就先“全总”先来:我要一个砂锅,里面+金针菇+海带。OK,

    全总的这个砂锅类:

          砂锅金针菇海带 extends 食物 {getCost() {return 砂锅4元+金针菇2元+海带1元}}

    鞠总的砂锅类:

          砂锅金针菇 extends 食物{getCost() {return 砂锅4元+金针菇2元}}

    接下来,公司又来了一堆MM。我要,砂锅+海带,我要砂锅+油豆腐,我要砂锅+豆腐干,我要……,我要……,发挥想象她到底要啥东西啊???

    OH,my lady gaga,每个MM的食物一个类,要“类爆炸”了,神呐救救我吧。

          这还不够,二楼的man还没说话呢,我要米饭+大排+小排+牛排(绝对的肉食动物),我要米饭+鲤鱼……又是一堆……

    神啊。装饰者模式披着超人的披风,头戴性感黑丝袜,飞到了红草莓餐厅。

          大家不要慌,我,装饰者模式先来介绍下自己(装饰者模式类图):

         装饰者模式

    既然知道了这个类图,咱们就直接将具体场景翻译成这个类图吧。就直接上中文类图了(非常不推荐的方法)。

      装饰者模式中文

    既然类图都出来了。那代码也就出来了。OK,下面直接实现代码吧。下面的代码中,类就直接用中文表示了。(实际操作中如果是这样操作,

    当然是要被项目经理先砍头,然后再分尸的!)。这里我用了两种语言:JAVA和C#

    JAVA食物类:

    package DesignPattern.DecoratorPattern;
     
    public abstract class 食物 {
        String name = "不知道什么食物";
        public String getName() {
        return name;
        }
     
        public abstract double getCost();
    }
    C#食物类:
        public abstract class 食物
        {
            protected String name = "不知道什么食物";
     
            public virtual String getName() {
                return name;
            }
     
            public abstract double getCost();
        }

    JAVA菜类:

    package DesignPattern.DecoratorPattern;
     
    public abstract class 菜 extends 食物 {
      //所有的菜装饰者都要重新实现getName()这个方法
        //为了之后显示主要食物和加了什么菜的。
        public abstract String getName();
    }

    C#菜类:

    /// <summary>
        /// Description of 菜.
        /// </summary>
        public abstract class 菜:食物
        {
            public 菜(){
            }        
        }

    JAVA砂锅类:

    package DesignPattern.DecoratorPattern;
     
    public class 砂锅 extends 食物 {
        // 构造函数
        public 砂锅() {
        name = "砂锅";
        }
     
        @Override
        public double getCost() {
        // TODO Auto-generated method stub
        return 4.0;
        }
     
    }

    C#砂锅类:

        /// <summary>
        /// Description of 米饭.
        /// </summary>
        public class 砂锅:食物
        {
            public override string getName()
            {
                return "砂锅";
            }
            public override double getCost()
            {
                return 4.0;
            } 
        }

    JAVA米饭类:

    package DesignPattern.DecoratorPattern;
     
    public class 米饭 extends 食物 {
        // 构造函数
        public 米饭() {
        name = "米饭";
        }
     
        @Override
        public double getCost() {
        // TODO Auto-generated method stub
        return 1.0;
        }
    }

    C#米饭类:

        /// <summary>
        /// Description of 米饭.
        /// </summary>
        public class 米饭:食物
        {
            public override double getCost()
            {
                return 1.0;
            }
            public 米饭(){
            
            }
            public override string getName()
            {
                return "米饭";
            }
     
        }

    JAVA香干类:

    package DesignPattern.DecoratorPattern;
     
    public class 香干 extends 菜 {
        食物 obj;
     
        public 香干(食物 obj) {
        this.obj = obj;
        }
     
        public String getName() {
        // TODO Auto-generated method stub
        return obj.getName() + ",+香干";
        }
     
        public double getCost() {
        // TODO Auto-generated method stub
        return 0.5 + obj.getCost();
        }
     
    }

    C#香干类:

    /// <summary>
        /// Description of 香干.
        /// </summary>
        public class 香干:菜
        {
            食物 obj;
            public override string getName()
            {
                return obj.getName()+",香干";
            }
            public override double getCost()
            {
                return 0.5+obj.getCost();
            }
            public 香干(食物 obj)
            {
                this.obj=obj;
            }
        }

    JAVA大排类:

    package DesignPattern.DecoratorPattern;
     
    public class 大排 extends 菜 {
        食物 obj;
     
        public 大排(食物 obj) {
        this.obj = obj;
        }
     
        public String getName() {
        // TODO Auto-generated method stub
        return obj.getName() + ",+大排";
        }
     
        public double getCost() {
        // TODO Auto-generated method stub
        return 4 + obj.getCost();
        }
    }

    C#大排类:

        public class 大排:菜
        {
            食物 obj;
            public override string getName()
            {
                return obj.getName()+",大排";
            }
            public override double getCost()
            {
                return 4+obj.getCost();
            }
            public 大排(食物 obj)
            {
                this.obj=obj;
            }
        }

    OK.所有的类搞定,接下来开始测试这个模式了。下面写一个main方法,太迟了,明天早上再写了。

    测试JAVA类:

    package DesignPattern.DecoratorPattern;
     
    public class Decorator {
     
        /**
         * @param args
         */
        public static void main(String[] args) {
        // TODO Auto-generated method stub
        食物 ricedan=new 米饭();
        System.out.println(ricedan.getName()+"  ¥"+ricedan.getCost());
        
        食物 rice = new 米饭();
        rice = new 大排(rice);    
        rice = new 香干(rice);
        System.out.println(rice.getName() + "  ¥" + rice.getCost());
        食物 tajines=new 砂锅();
        tajines=new 香干(tajines);
        System.out.println(tajines.getName()+"  ¥"+tajines.getCost());
        }
    }

    测试结果:

    米饭  ¥1.0
    米饭,大排,香干  ¥5.5
    砂锅,香干  ¥4.5

    C#版本:

    /*
     * Created by SharpDevelop.
     * User: qiyj
     * Date: 2010-4-13
     * Time: 2:34
     * 
     * To change this template use Tools | Options | Coding | Edit Standard Headers.
     */
     using System;
     
     namespace ConsoleProject
    {
     public class A
        {
        public static void Main()
            {
            食物 rice=new 米饭();
            Console.WriteLine(rice.getName()+"  ¥"+rice.getCost());
            食物 rice2=new 米饭();
            rice2=new 大排(rice2);
            Console.WriteLine(rice2.getName()+"  ¥"+rice2.getCost());
            Console.ReadKey();
            }
        }
     }

    结果:

    米饭  ¥1

    米饭,大排 ¥5

    总结:

         在使用装饰者模式中,用到了抽象类,没有用到接口,当然最好的情况是用接口,但是普遍都是使用抽象类的,GOF里面都这么说的,这就是约定吧。当然在测试程序里面,我们可以使用工厂模式来产生相应的装饰者,之后会有用到。

  • 相关阅读:
    【t083】买票
    基于Linux应用层的6LOWPAN物联网网关及实现方法
    Express的路由详解
    day18 8.jdbc中设置事务隔离级别
    day18-事务与连接池 6.事务隔离级别与解决问题
    day36-hibernate检索和优化 02-Hibernate检索方式:简单查询及别名查询
    day37-hibernate 02-Hibernate二级缓存:二级缓存的散装数据
    day36-hibernate检索和优化 01-上次课内容回顾
    day36-hibernate检索和优化 05-Hibernate检索方式:离线条件查询
    SQL Server 涉及数据库安全常用SQL语句
  • 原文地址:https://www.cnblogs.com/UpThinking/p/1710719.html
Copyright © 2020-2023  润新知