这是我想出的唯一解决方案,它在分配给这封信之后仍然有意义(尽管我认为这不是一个“好”的解决方案 - 请参阅下面的注释):ComputerOrder
andPartyTrayOrder
可以提供仅接受以下特殊类型Product
:
abstract class Product {}
class ComputerPart extends Product {}
class Peripheral extends Product { }
class Cheese extends Product {}
class Fruit extends Product {}
class Service extends Product {}
abstract class GenericOrder<T extends Product> {
protected final void addImpl(T t) {
}
}
class ComputerOrder extends GenericOrder<Product> {
void add(ComputerPart t) {
addImpl(t);
}
void add(Peripheral t) {
addImpl(t);
}
void add(Service t) {
addImpl(t);
}
}
class PartyTrayOrder extends GenericOrder<Product> {
void add(Cheese t) {
addImpl(t);
}
void add(Fruit t) {
addImpl(t);
}
void add(Service t) {
addImpl(t);
}
}
这样,订单实现可以完全接受正确的类型:
public class ProductExample {
public static void main(String[] args) {
ComputerOrder c = new ComputerOrder();
c.add(new ComputerPart());
c.add(new Peripheral());
//c.add(new Cheese()); // Not allowed
//c.add(new Fruit()); // Not allowed
c.add(new Service());
PartyTrayOrder p = new PartyTrayOrder();
//p.add(new ComputerPart()); // Not allowed
//p.add(new Peripheral()); // Not allowed
p.add(new Cheese());
p.add(new Fruit());
p.add(new Service());
}
}
我认为这是预期的解决方案,因为作业包含广泛的提示:
根据需要实施尽可能多的方法。
因此,最有可能的目标不是实现一种神奇地绑定到多个类的方法。相反,必须为每个“类别”添加一种方法。
顺便说一句:我的直觉是这种设计可以改进。想象一下,您必须为新类型的订单创建类等CarOrder
。FahsionOrder
或者想象一下,PartyTrayOrder
必须将其扩展为也处理类似Meat
or Dip
or的类Salad
:你最终会得到几十个类和几十个专门的方法。
这一切都可以通过引入与特定“订单类型”可接受的类型完全匹配的专用“产品类型”来避免。所以我认为 (Product
应该是一个开始的接口,并且) 应该有类似ComputerProduct
and的接口PartyTrayProduct
,如
interface Product {}
interface ComputerProduct extends Product {}
class ComputerPart implements ComputerProduct {}
class Peripheral implements ComputerProduct {}
interface PartyTrayProduct extends Product {}
class Cheese implements PartyTrayProduct{}
class Fruit implements PartyTrayProduct{}
class Service implements Product {}
class DeliveryService implements PartyTrayProduct{}
class AssemblyService implements ComputerProduct {}
这样,特定的所需边界ComputerOrder
和PartyTrayOrder
已经使用类层次结构建模。这样做的好处是:你不再需要ComputerOrder
andPartyTrayOrder
类了!然后GenericOrder
可能是非抽象的,为了创建特定类型的订单,您只需正确使用泛型类型绑定。
这是一个完整的示例,我刚刚Salad
将其作为一个新的PartyTrayProduct
,CarPart
作为一种新类型的产品投入使用,而无需扩展或修改任何“基础设施类”:
interface Product {}
interface ComputerProduct extends Product {}
class ComputerPart implements ComputerProduct {}
class Peripheral implements ComputerProduct {}
interface PartyTrayProduct extends Product {}
class Cheese implements PartyTrayProduct{}
class Fruit implements PartyTrayProduct{}
class Service implements Product {}
class DeliveryService implements PartyTrayProduct{}
class AssemblyService implements ComputerProduct {}
class Salad implements PartyTrayProduct{} // A new PartyTrayProduct
// Entirely new product type:
interface CarProduct extends Product {}
class CarPart implements CarProduct {}
class CarInterior implements CarProduct {}
class GenericOrder<T extends Product> {
public void add(T t) { }
}
public class ProductExample2 {
public static void main(String[] args) {
GenericOrder<ComputerProduct> c = new GenericOrder<ComputerProduct>();
c.add(new ComputerPart());
c.add(new Peripheral());
//c.add(new Cheese()); // Not allowed
//c.add(new Fruit()); // Not allowed
c.add(new AssemblyService());
GenericOrder<PartyTrayProduct> p = new GenericOrder<PartyTrayProduct>();
//p.add(new ComputerPart()); // Not allowed
//p.add(new Peripheral()); // Not allowed
p.add(new Cheese());
p.add(new Fruit());
p.add(new Salad()); // Just add it...
p.add(new DeliveryService());
// Easy to extend:
GenericOrder<CarProduct> e = new GenericOrder<CarProduct>();
e.add(new CarPart());
e.add(new CarInterior());
}
}