Design patterns 行为的特征或凌驾于行为之上的
我左右为难,在以下情况下,哪一个更好:Design patterns 行为的特征或凌驾于行为之上的,design-patterns,overriding,traits,Design Patterns,Overriding,Traits,我左右为难,在以下情况下,哪一个更好: Movie | ActionMovie HorrorMovie ChristmasMovie ... | | | AdultActionMovie AdultHorrorMovie AdultChristmasMovie 在电影中有一个观看功能,对于成人电影你需要检查18+ 因此,我: void watch(viewer) { if(check(viewer)) { .. enjoy mo
Movie
|
ActionMovie HorrorMovie ChristmasMovie ...
| | |
AdultActionMovie AdultHorrorMovie AdultChristmasMovie
在电影中有一个观看功能,对于成人电影你需要检查18+
因此,我:
void watch(viewer) {
if(check(viewer)) {
.. enjoy movie
}
else
.. you don't fit requirements
}
入住动作片恐怖片圣诞电影
bool check(viewer) {
return true; // nothing to check
}
登记成人电影成人电影成人电影成人圣诞节电影
bool check(viewer) {
return viewer.age >= 18; // check age
}
现在真正的问题是:我应该在成人类(以及可能的其他子类)中覆盖检查吗,还是我应该使用两个特征,一个提供动作电影等使用的正常检查方法(返回true),另一个(年龄>18岁)成人班使用哪一种
请提供一个理由,为什么你应该选择一个高于另一个,因为在我看来,这些是完全相同的
谢谢。我知道您的问题是关于特性/方法重写的,但我相信您正在处理的场景与使用继承对解决方案建模的方式有关 请注意,要将电影表达为成人电影,必须为每种类型的电影创建一个新类,这也会在
watch
方法中反映为复制
另外,如果需要添加一种新的电影,比如说commyMovie
,您还需要创建AdultComedyMovie
。如果您还需要处理儿童电影,那么最终将得到AdultComedyMovie
,ChildComediMovie
,等等
分析在你的模型中,你似乎缺少了电影的收视率和类型。这就是为什么流派/评级的爆炸式增长在等级结构的底层表现得淋漓尽致 请注意,如果您有成人和儿童,则解决方案中需要的类数等于1(
Movie
)+N(#流派)+2N(每个评级需要额外的类)
您可以建模评级
以实现许多您想要的功能(成人、儿童等),而无需更改电影建模的方式
你没说什么流派,所以我假设一个符号/字符串就足以代表它们
这样,您只需要一个类来表示电影,Movie
,一个类来表示分级,AdultRating
型号
下面是可能用于解决设计问题的类的快速描述。
为了简单起见,当有人要求看电影时,我决定将检查和验证分开
电影
在您的问题域中为电影建模。知道它属于哪种类型和它的评级
评级
封装了观看电影时应满足的限制条件。不同的评级将有不同的实施(成人、儿童)
检票员
你可以把它想象成一个员工在礼堂入口处索要门票,并决定是否允许你观看电影 警告:
TicketController
是一个错误的名称。“Controller”使用过度,可能意味着很多不同的东西,因此请为它找到一个更好的名称:)
常规实施
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);
}
}
用法
假设您有电影、TicketController和查看器的实例:
void watch(aViewer, aMovie) {
ticketController.isAllowedToWatch(aViewer, aMovie);
// proceed with the original stuff :)
... enjoy movie
}