你可以删除装饰器吗? [英] Can you remove a decorator?

查看:156
本文介绍了你可以删除装饰器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以从对象中删除装饰器吗?

Is it possible to remove a decorator from an object?

说我有以下代码:

abstract class Item
{
    decimal cost();
}

class Coffee : Item
{
    decimal cost()
    { // some stuff }
}

abstract class CoffeeDecorator : Item
{
    Item decoratedItem;
}

class Mocha : CoffeeDecorator 
{
    Item decoratedItem;

    public Mocha(Coffee coffee)
    {
       decoratedItem = coffee;
    }
}

public void Main(string[] args)
{
    Item coffeeDrink = new Mocha(new Coffee());
}

有没有办法从我的新消息中删除新的摩卡车() 咖啡对象?

Is there a way to remove the "new Mocha()" from my new "coffee" object?

编辑:澄清 - 我想要删除一个装饰器,而不是全部。所以如果我在Coffee对象上有一个摩卡装饰师和一个Sugar装饰器,我想知道我是否可以删除Mocha装饰器。

Clarification - I want to be able to remove just ONE decorator, not all of them. So if I had a Mocha decorator AND a Sugar decorator on the Coffee object, I want to know if I can remove just the "Mocha" decorator.

推荐答案

首先,此作业不合法:

Coffee coffee = new Mocha(new Coffee());

A 摩卡不是 Coffee 也没有从摩卡 Coffee 的隐式转换。为了删除装饰器,您需要提供方法或演员来进行。所以你可以在 Mocha 中添加一个非常方便的方法:

A Mocha is not a Coffee nor is there an implicit cast from a Mocha to a Coffee. To "remove" the decorator, you need to provide either a method or a cast to do so. So you could add an undecorate method to Mocha:

public Coffee Undecorate() {
    return (Coffee)decoratedItem;
}

然后你可以说

Coffee coffee = new Mocha(new Coffee()).Undecorate();

或者,您可以在摩卡中提供一个隐式转换运算符 class:

Alternatively, you could provide an implicit cast operator in the Mocha class:

public static implicit operator Coffee(Mocha m) {
    return (Coffee)m.decoratedItem;
}

然后你的行

Coffee coffee = new Mocha(new Coffee());

将合法。

你的问题表明对设计模式有潜在的误解(实际上,你的实现也是这样)。你想做的是很臭使用装饰图案的正确方法就是这样。请注意, CoffeeDecorator 派生自咖啡

Now, your question suggests a potential misunderstanding of the design pattern (and, in fact, your implementation suggests one too). What you're trying to do is very smelly. The right way to go about using the decorator pattern is like so. Note that CoffeeDecorator derives from Coffee!

abstract class Item { public abstract decimal Cost(); }
class Coffee : Item { public override decimal Cost() { return 1.99m; } }
abstract class CoffeeDecorator : Coffee {
    protected Coffee _coffee;
    public CoffeeDecorator(Coffee coffee) { this._coffee = coffee; }
}
class Mocha : CoffeeDecorator {
    public Mocha(Coffee coffee) : base(coffee) { }
    public override decimal Cost() { return _coffee.Cost() + 2.79m; }
}
class CoffeeWithSugar : CoffeeDecorator {
    public CoffeeWithSugar(Coffee coffee) : base(coffee) { }
    public override decimal Cost() { return _coffee.Cost() + 0.50m; }
}

然后你可以说:

Coffee coffee = new Mocha(new CoffeeWithSugar(new Coffee()));
Console.WriteLine(coffee.Cost()); // output: 5.28

鉴于此,您需要进行何种修改?

Given this, what do you need to undecorate it for?

这篇关于你可以删除装饰器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆