- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在学习使用装饰器模式的过程中,遇到了一个我认为很简单但似乎找不到答案的问题。假设我有一个抽象的 Beverage 类。然后假设我有一些扩展 Beverage 的具体组件:美式咖啡、浓缩咖啡、拿铁等。还有一个扩展 Beverage 的抽象 Condiment 类。 Condiments 类有多个子类:milk、sugar、soy、wip。每个调味品子类都有一个分别从 Beverage 和 Condiments 继承的 cost 和 getdescription() 方法。我的问题是,如何在测试时阻止某个 Beverage 实例具有与其关联的不止一种相同类型的调味品,即即使在测试类中两次提到大 bean ,美式咖啡只收取一次大 bean 费用。我知道我可以将调味品保存到列表中并在添加新调味品时检查它是否存在,我只是想看看是否存在更好的选择。
饮料类
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
调味品装饰师
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
黑烤类
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "Dark Roast Coffee";
}
public double cost() {
return .99;
}
}
大 bean 类
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Soy";
}
public double cost() {
return .15 + beverage.cost();
}
}
如果有人能帮助我,甚至指出一篇好文章或教程,我将不胜感激。
最佳答案
听起来像 Head First Design Patterns (HFDP) 中的示例?测试用例简单易懂,但做起来可能没那么多。
将装饰器视为包装器。当装饰器要包装某些东西时,它可以检查那个“东西”以查看它是否已经包含它自己类型的装饰器。下面是我稍微改动过的 HFDP 代码:
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Soy(beverage2); // wrap once
beverage2 = new Soy(beverage2); // wrap again (**error case)
您必须决定是否要禁止对所有装饰器进行多次包装,或者某些装饰器可能具有一种“仅一次”属性。另一件要决定的事情是如果发生第二次换行(上面注释中的 ** )或者您是否只想忽略 cost()
中的额外换行是否失败(抛出异常)。
如果您在 wrap-time 停止多次包装,它可能会更干净并且更不容易出错。那将在构造函数中。您可以在抽象类中编写一个通用函数,使用反射检查它(在不支持它的语言中不起作用),或者解析包装对象的描述以找到它自己的字符串(如果装饰不可靠,则不太可靠)没有唯一的名称)。
我看到这样做的最大问题是调味品包装饮料,并且根据设计(信息隐藏),调味品不会“知道”它们正在包装其他调味品。您编写的任何代码都可能是脆弱的(它可能违反开闭原则)。然而,这就是设计中的权衡。您不可能拥有一切,因此请决定什么更重要(停止多重包装,或采用允许添加新装饰器而不破坏任何东西的设计)。
使用 getDescription(解析它)可能最有意义,前提是您可以依赖该格式来识别嵌套。
Soy 类可以这样做:
private String myDescription = "Soy"
public Soy(Beverage beverage) {
if (beverage.getDescription().contains(myDescription)) {
throw new Exception();
}
this.beverage = beverage;
}
但更好的方法可能是 .split()
在 ","字符上并检查这些字符串,因为描述只是使用逗号连接(在 getDescription()
).
正如我所说,如果禁止所有多个调味品包装是一般规则,您可以将此逻辑重构到 CondimentDecorator 类以避免重复代码。您甚至可以使用 Decorator boolean 属性来表示“allowsMultiple”并对其进行编码。
关于java - Decorator方法,Java中的一种Decorator类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22211309/
我正在尝试编写一个相当多态的库。我遇到了一种更容易表现出来却很难说出来的情况。它看起来有点像这样: {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE
谁能解释一下这个表达式是如何工作的? type = type || 'any'; 这是否意味着如果类型未定义则使用“任意”? 最佳答案 如果 type 为“falsy”(即 false,或 undef
我有一个界面,在IAnimal.fs中, namespace Kingdom type IAnimal = abstract member Eat : Food -> unit 以及另一个成功
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
在 C# 中,default(Nullable) 之间有区别吗? (或 default(long?) )和 default(long) ? Long只是一个例子,它可以是任何其他struct类型。 最
假设我有一个案例类: case class Foo(num: Int, str: String, bool: Boolean) 现在我还有一个简单的包装器: sealed trait Wrapper[
这个问题在这里已经有了答案: Create C# delegate type with ref parameter at runtime (1 个回答) 关闭 2 年前。 为了即时创建委托(dele
我正在尝试获取图像的 dct。一开始我遇到了错误 The function/feature is not implemented (Odd-size DCT's are not implemented
我正在尝试使用 AFNetworking 的 AFPropertyListRequestOperation,但是当我尝试下载它时,出现错误 预期的内容类型{( “应用程序/x-plist” )}, 得
我在下面收到错误。我知道这段代码的意思,但我不知道界面应该是什么样子: Element implicitly has an 'any' type because index expression is
我尝试将 SignalType 从 ReactiveCocoa 扩展为自定义 ErrorType,代码如下所示 enum MyError: ErrorType { // .. cases }
我无法在任何其他问题中找到答案。假设我有一个抽象父类(super class) Abstract0,它有两个子类 Concrete1 和 Concrete1。我希望能够在 Abstract0 中定义类
我想知道为什么这个索引没有用在 RANGE 类型中,而是用在 INDEX 中: 索引: CREATE INDEX myindex ON orders(order_date); 查询: EXPLAIN
我正在使用 RxJava,现在我尝试通过提供 lambda 来订阅可观察对象: observableProvider.stringForKey(CURRENT_DELETED_ID) .sub
我已经尝试了几乎所有解决问题的方法,其中包括。为 提供类型使用app.use(express.static('public'))还有更多,但我似乎无法为此找到解决方案。 index.js : imp
以下哪个 CSS 选择器更快? input[type="submit"] { /* styles */ } 或 [type="submit"] { /* styles */ } 只是好
我不知道这个设置有什么问题,我在 IDEA 中获得了所有注释(@Controller、@Repository、@Service),它在行号左侧显示 bean,然后转到该 bean。 这是错误: 14-
我听从了建议 registering java function as a callback in C function并且可以使用“简单”类型(例如整数和字符串)进行回调,例如: jstring j
有一些 java 类,加载到 Oracle 数据库(版本 11g)和 pl/sql 函数包装器: create or replace function getDataFromJava( in_uLis
我已经从 David Walsh 的 css 动画回调中获取代码并将其修改为 TypeScript。但是,我收到一个错误,我不知道为什么: interface IBrowserPrefix { [
我是一名优秀的程序员,十分优秀!