特质或压倒行为

时间:2014-12-24 09:25:32

标签: design-patterns override traits

在下列情况下,我有一个两难的好处:

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)?

请提供一个理由,为什么你应该选择一个在另一个之上,因为在我看来这些是完全相同的?

感谢。

1 个答案:

答案 0 :(得分:1)

我知道你的问题是关于traits / method overriding,但我相信你所处理的场景与继承用于建模解决方案的方式有关。

请注意,要为成人表达电影,必须为每种类型的电影创建一个新类,并且这些类也会在watch方法中反映为重复。

此外,如果需要添加新类型的电影,例如ComedyMovie,您还需要创建AdultComedyMovie。如果您还需要处理儿童电影,最终会得到AdultComedyMovieChildComediMovie,等等。

<强>分析
您似乎错过了模型中的电影评级和类型。这就是为什么类型/评级的爆炸在层次结构底部显示出来的原因。

请注意,如果您有成人和儿童,您的解决方案中所需的课程数量等于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
}