如何合理设计多个子类的组合?

时间:2016-07-23 15:16:08

标签: java multiple-inheritance

我有一个父类 - Product

public abstract class Product {}

扩展它的3个子类:

  1. public class Vinyl extends Product {}

  2. public class Book extends Product {}

  3. public class Video extends Product {}

  4. 所有子类都使用其特定实现覆盖preview()方法。 现在,我有一个新的设计需求:我需要定义vinyl&的组合项目。 book也有preview()方法(这是乙烯基和书籍的组合)。在说明中它说我可以创建Interface \ class字段成员或我想支持它的任何实现,但我不确定具体如何。

    新设计是否也应该使用inheritance实现,还是应该更改当前设计?

2 个答案:

答案 0 :(得分:5)

  

新设计是否也应该使用继承实现,还是应该更改当前设计?

新设计可以纯粹通过继承实现。但是真正的问题在于你会有太多的子类。您可以轻松地创建一个名为let control = BetterSegmentedControl( frame: CGRect(x: 0.0, y: 100.0, width: view.bounds.width, height: 44.0), titles: ["One", "Two", "Three"], index: 1, backgroundColor: UIColor(red:0.11, green:0.12, blue:0.13, alpha:1.00), titleColor: .whiteColor(), indicatorViewBackgroundColor: UIColor(red:0.55, green:0.26, blue:0.86, alpha:1.00), selectedTitleColor: .blackColor()) control.titleFont = UIFont(name: "HelveticaNeue", size: 14.0)! control.selectedTitleFont = UIFont(name: "HelveticaNeue-Medium", size: 14.0)! control.addTarget(self, action: #selector(ViewController.controlValueChanged(_:)), forControlEvents: .ValueChanged) view.addSubview(control) 的{​​{1}}的新子类,并完成它。但是当你必须引入另一个组合时会发生什么,比如Product。您还必须为此创建一个新的子类,依此类推。

解决方案是一起使用继承和组合。复合模式非常适合这个问题。根据维基百科:

  

复合模式描述了一组对象的处理方式与对象的单个实例相同。通过实现复合模式,客户可以统一处理单个对象和组合。

首先定义一个VinylBook

VinylVideo

您现在拥有复合产品,其行为就像是一个产品,允许您动态创建组合产品,而无需为每个组合创建新的子类。

如何动态创建产品的示例:

CompositeProduct

如果您希望动态地为产品添加其他行为,也可以查看Decorator模式。

答案 1 :(得分:0)

我想提供一个替代方案,因为我对另一个解决方案并不满意。(不要误解我,它简单直接,复合概念也很很好的学习和用户也提到了它真正有用的装饰模式。

我对这个解决方案的问题是你给产品(无论哪个),然后你能做什么?

让我们想象

public abstract class Product {
    abstract void preview();
}

现在你的CompositeProduct非常通用,只能实现类似这样的东西

void preview(){
    for(Product product : products) product.preview();
}

我敢打赌,这不是你想要的。

我的另一种方法是通过接口使用Composition。我无法详细说明域名,所以我举一个简单的例子。

什么是书?让我们想象一下可读的东西。

public interface Readable { void read(); }

public class Book extends Product implements Readable {}

什么是乙烯基? Showable

public interface Showable { void show(); }

public class Vinyl extends Product implements Showable {}

现在BookVinyl就是

public class BookVinyl extends Product implements Readable, Showable { }

这会给你带来什么?好吧,现在BookVinyl就像一本书一样可以阅读,就像乙烯基一样。和预览?它可以显示然后阅读或其他任何内容。