【发布时间】:2012-05-01 18:58:15
【问题描述】:
我已将实际代码简化为说明这一点的最小示例。请原谅缺少 setter/getter 等。
假设我们有几个网页,客户按顺序浏览。这里的用例是:-
- 用户选择他们想要的书
- 用户选择是否希望通过邮寄或电子邮件发送信息以及相关详细信息
- 系统完成订单
这个问题的重点是两种交付方式。这建模如下:
interface DeliveryDetails
{
// Implementations of this have nothing in common other than that they
// fulfil the same logical role.
}
class EmailDeliveryDetails implements DeliveryDetails
{
String emailAddress; // It really has a constructor and getter, I promise.
}
class PostalDeliveryDetails implements DeliveryDetails
{
String streetAddress;
String Country;
}
现在,为了表示用户在浏览页面时输入的信息,我们有这个类:
class PurchaseData
{
String title;
DeliveryDetails deliveryDetails;
}
当用户浏览网页时,信息存储在PurchaseData 的实例中。如果用户返回一个页面,我们可以向他们展示他们之前输入的内容。在用户确认并交付图书后,deliveryDetails 引用了 PostalDeliveryDetails 或 EmailDeliveryDetails 的实例。
总之,当用户确认他们的信息时:
// Some code in a factory
if ( purchaseData.deliveryDetails instanceof EmailDelivery )
{
// construct a EmailDeliveryService( purchaseData, SMTP details, etc ... )
}
if ( purchaseData.deliveryDetails instanceof PostalDelivery )
{
// construct a PostalDeliveryService( purchaseData, etc ... )
}
}
困扰我的是Delivery接口没有方法。
这是由于电子邮件和邮政递送之间的差异所造成的。
我不认为DeliveryDetails.deliver() 是一个好方法,因为这会强制实现静态获取诸如 SMTP 服务器地址之类的东西。这会混淆关注点(管道与用户输入的信息)。
如果您必须存储任意类型的内容,泛型可能会很有用。无法使用泛型 (PurchaseData<T extends Delivery>),因为在创建 PurchaseData 实例时不知道交付类型。无论如何,这对工厂没有帮助。
这个空界面可以吗?有没有更好的方法来设计这段代码?
【问题讨论】:
-
我没有看到空接口有任何问题。这样的界面我见过很多次了,用你的方法看起来还不错。
标签: oop marker-interfaces