我有一个父类 - Product
public abstract class Product {}
扩展它的3个子类:
public class Vinyl extends Product {}
public class Book extends Product {}
public class Video extends Product {}
所有子类都使用其特定实现覆盖preview()
方法。
现在,我有一个新的设计需求:我需要定义vinyl
&的组合项目。 book
也有preview()
方法(这是乙烯基和书籍的组合)。在说明中它说我可以创建Interface \ class字段成员或我想支持它的任何实现,但我不确定具体如何。
新设计是否也应该使用inheritance
实现,还是应该更改当前设计?
答案 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就像一本书一样可以阅读,就像乙烯基一样。和预览?它可以显示然后阅读或其他任何内容。