大话设计模式-装饰者模式C#与Java对比存在的问题

最近看了大话设计模式书中的装饰者模式,然后用C#照着写了一遍,发现运行出来的结果和书上不一样,然后又用Java写了一遍 和书上一样,同样的代码,不同的编译器与运行环境,Java和.NET 下面贴上代码

首先是Java实现

Beverage(饮料抽象类)

CondimentDecorator(调料抽象类,继承Beverage)

Latte(拿铁饮料,继承Beverage)

Mocha(摩卡调料,继承CondimentDecorator)

public abstract class Beverage {
    public String description = "Unkonw";
    public String getDescription(){
        return description;
    }
    public abstract double cost();
}
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}
public class Latte extends Beverage {
    public Latte(){
        description = "Latte Coffee";
    }
    @Override
    public double cost() {
        // TODO Auto-generated method stub
        return 21.05;
    }
}
public class Mocha extends CondimentDecorator {

    Beverage beverage;
    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        // TODO Auto-generated method stub
        return beverage.getDescription() + ", Mocha Condiment";
    }
    @Override
    public double cost() {
        // TODO Auto-generated method stub
        return .99 + beverage.cost();
    }

}
public static void main(String[] args) {
        // TODO Auto-generated method stub

        Beverage beverage1 = new Latte();
        beverage1 = new Mocha(beverage1);
        System.out.println("小明点了:"+beverage1.getDescription()+"咖啡,花了:"+beverage1.cost()+" RMB");
    }

运行结果

下面看下C#中的实现

Beverage(饮料抽象类)

CondimentDecorator(调料抽象类,继承Beverage)

Espresso(浓咖啡,继承Beverage)

SoyMilk(豆奶调料,继承CondimentDecorator)

public abstract class Beverage
    {
        public string description = "Unknow";
        public string getDescription()
        {
            return description;
        }

        public abstract double cost();

    }
public abstract class CondimentDecorator:Beverage
    {
        public abstract string getDescription();
    }
public class Espresso :Beverage
    {
        public Espresso()
        {
            description = "Espresso Coffee(浓咖啡)";
        }

        public override double cost()
        {
            return 19.00;
        }
    }
public class SoyMilk:CondimentDecorator
    {
        private Beverage beverage;
        public SoyMilk(Beverage bev)
        {
            this.beverage = bev;
        }

        public override string getDescription()
        {
            return beverage.getDescription() + "SoyMilk(豆奶调料)";
        }

        public override double cost()
        {
            return 1.25 + beverage.cost();
        }
    }
public static void Main(string[] args)
        {
            Beverage espresso = new Espresso();
            espresso = new SoyMilk(espresso);
            Console.WriteLine("小张点了一杯:" + espresso.getDescription() + " 咖啡, 价格是:" + espresso.cost() + " RMB");

            Console.ReadLine();
        }

可以看出,除了饮料名称之外,代码都是一样的,下面是运行结果

和上面Java的结果对比确实不一样,下面把C#中的Beverage和CondimentDecorator改一下

把Beverage的getDescription方法写成虚方法

public virtual string getDescription()
        {
            return description;
        }

然后把CondimentDecorator的加上override

public abstract override string getDescription();

下面是运行结果

这样就正常了,是不是很神奇

来分析一下Java中执行步骤

Beverage beverage1 = new Latte(); //父类实例化Latte
        beverage1 = new Mocha(beverage1); //Latte作为参数实例化Mocha
        //beverage1getDescription首先调用Mocha中的getDescription方法,然后再调用Latte里面的getDescription方法(隐式继承了父类)
beverage1.getDescription();

一直搞不懂C#中这样到底是怎么执行的,有了解的请给我留言,万分感谢

时间: 2024-08-28 18:12:58

大话设计模式-装饰者模式C#与Java对比存在的问题的相关文章

设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 使用方法

装饰者模式(Decorator Pattern) Java的IO类 使用方法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716823 装饰者模式(decorator pattern)参见: http://blog.csdn.net/caroline_wendy/article/details/26707033 Java的IO类使用装饰者模式进行扩展, 其中FilterInputStream类, 就是装饰者(decora

设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 用法

装饰者模式(Decorator Pattern) Java的IO类 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716823 装饰者模式(decorator pattern)參见: http://blog.csdn.net/caroline_wendy/article/details/26707033 Java的IO类使用装饰者模式进行扩展, 当中FilterInputStream类, 就是装饰者(decorato

大话设计模式_备忘录模式(Java代码)

备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 简单描述:一个Memento类,代表Originator中要备份的属性.Originator负责生成备份和还原备份,CareTaker负责存储备份 大话设计模式中的截图: 例子代码: Memento类: 1 package com.longsheng.memento; 2 3 public class Memento { 4 5 private String sta

大话设计模式_解释器模式(Java代码)

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 简单描述:一个AbstractExpression类,多个子类,存在一个Interpret方法,转义Context对象的信息.客户端根据信息实例化不同的Expression类,并调用其转义方法(这个过程可以使用简单工厂+反射进行) 大话设计模式中的截图: 代码例子: 假设HTML代码解释器: (1)第一类标签<HTML>(开始)/<HEAD>(头信息)/<BODY&g

大话设计模式_原型模式(Java代码)

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 简单描述:即通过实现接口Cloneable重写方法clone(),使得创建新的拷贝对象不需要一个成员一个成员的重新复制,而且可以提高创建对象的效率 Java中要想实现拷贝使用clone()方法,类必须实现Cloneable接口,并且重写Object类中的clone()方法,调用父类的clone()方法即可实现浅复制 代码如下: WorkExperience类: 1 package com.longsheng.prototy

大话设计模式_模板方法模式(Java代码)

模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 简单描述:多个类的行为是差不多的,只是某些局部不一样,则交由父类中抽象出这些子类中相同的部分,父类中定义出不同的部分的接口(方法),这些不同部分的方法则由子类去实现,通过多态,实现代码的重用 大话设计模式中的截图: 例子代码: AbstractClass类: 1 package com.longsheng.templatemethod; 2 3 public

java设计模式------装饰着模式

java设计模式-------装饰者模式 装饰者模式 Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案.主要有组件(components)和装饰器(Decorator)组成.要求components和Decorator实现相同的接口或者抽象类(具体类的局限性太大). 设计原则.模式特点.适用性 - 1. 多用组合,少用继承. 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为.然而,如果能够利用

大话设计模式_状态模式(Java代码)

状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 简单描述:一个Context类(存有一个抽象状态State引用),调用状态类的方法.State的具体类方法中会判断Context类的状态(如时间),满足一个状态则执行相应动作,否则把Context的State引用指向下一个状态类,由下一个状态类决定相应行为 大话设计模式中的截图: 例子代码: Work类(Context): 1 package com.longsheng.state; 2 3 public cla

大话设计模式_建造者模式(Java代码)

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 简单描述:1个产品类(可有可无,关键是建造流程),1个抽象建造步骤类,多个具体建造子类(不同的类建造不同的产品),1个指挥者(用于规定建造流程),客户端指定需要建造的具体类型,由指挥者建造好之后,建造者子类返回对应产品给客户 大话设计模式中的截图: 例子代码: Product类: 1 package com.longsheng.builder; 2 3 public class Product { 4 5 pr