Movie
|
ActionMovie HorrorMovie ChristmasMovie ...
| | |
AdultActionMovie AdultHorrorMovie AdultChristmasMovie
在电影中有一个手表功能,对于成人电影你需要检查18+ 所以我有:
void watch(viewer) {
if(check(viewer)) {
.. enjoy movie
}
else
.. you don't fit requirements
}
检查ActionMovie HorrorMovie ChristmasMovie ......
bool check(viewer) {
return true; // nothing to check
}
检查AdultActionMovie AdultHorrorMovie AdultChristmasMovie
bool check(viewer) {
return viewer.age >= 18; // check age
}
现在真正的问题是:我应该覆盖检查成人课程(以及可能的其他子类),或应该< strong>使用两个特征,一个提供由ActionMovie等使用的正常检查方法(返回true),另一个提供成人类使用的另一个(age&gt ;; 18)?
请提供一个理由,为什么你应该选择一个在另一个之上,因为在我看来这些是完全相同的?
感谢。
答案 0 :(得分:1)
我知道你的问题是关于traits / method overriding,但我相信你所处理的场景与继承用于建模解决方案的方式有关。
请注意,要为成人表达电影,必须为每种类型的电影创建一个新类,并且这些类也会在watch
方法中反映为重复。
此外,如果需要添加新类型的电影,例如ComedyMovie
,您还需要创建AdultComedyMovie
。如果您还需要处理儿童电影,最终会得到AdultComedyMovie
,ChildComediMovie
,等等。
<强>分析强>
您似乎错过了模型中的电影评级和类型。这就是为什么类型/评级的爆炸在层次结构底部显示出来的原因。
请注意,如果您有成人和儿童,您的解决方案中所需的课程数量等于1(Movie
)+ N(#genres)+ 2N(每个评级额外的课程)。
你可以建模Rating
来实现你想要的(成人,儿童等),而不必改变电影的建模方式。
你没有对流派说什么,所以我假设一个符号/字符串足以代表它们。
这样,您只需要一个班级来代表电影,Movie
和一个班级来代表评分,AdultRating
。
<强>模型强>
以下是您可能用于解决设计问题的类的快速说明。 为了简单起见,当有人要求观看电影时,我决定将检查和验证分开。
Movie
在问题域中为电影建模。知道它属于哪种类型并且它的评级。
Rating
封装一个人为了观看电影而应该满足的限制。不同的评级将有不同的实施(成人,儿童)。
Ticket Controller
您可以将其视为礼堂入口处的员工,要求购买门票,并决定是否允许您观看电影。
警告:TicketController
是一个错误的名称。 “控制器”被过度使用,可能意味着很多不同的东西,所以请为它找到一个更好的名称:)
Vanilla Implemention
class TicketController
public void isAllowedToWatch(aViewer, aMovie) {
if !aMovie.isRecommendedFor(aViewer) {
throw new Exception("You're not allowed to watch this movie");
}
}
}
class Movie
public void new(aRating, aGenre) {
rating = aRating;
genre = aGenre; // unused
}
public bool isRecommendedFor(aViewer) {
return rating.isSatisfiedBy(aViewer);
}
}
public class AdultRating
public bool isSatisfiedBy(aViewer) {
return aViewer.isOlderThan(18);
}
}
<强>用法强>
假设你有Movie,TicketController和一个查看器的实例:
void watch(aViewer, aMovie) {
ticketController.isAllowedToWatch(aViewer, aMovie);
// proceed with the original stuff :)
... enjoy movie
}