A Look At Design

    在开始介绍各种Controller之前,我们先来讨论个重要的设计原则。在学习不同的Controller的时候,一个Spring的新手会遇到大量的标示为final的方法,这些情况常常发生在子类中覆写Controller的一些方法的时候。虽然这让我们很沮丧,但是这样做,是有重要的原因的。
    想要了解Spring开发者的意图,我们必须要知道面向对象设计(object-oriented design)中所强调开闭原则(Open-Closed Principle).这个原则定义如下:软件实体必须对扩展开放,对修改关闭(Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification). 换句话说,这个原则强调的是一个类必须保护自己被改变的同时还要良好的支持扩展(a class should protect itself from alteration while at the same time providing well-defined extension points)。
    猛地一看,感觉这两个目标好像是相互矛盾的,除了扩展之外还有其他的方式改变一个类行为吗?一个良好的面向对象设计会在封装(encapsulation)上给与很大的力度,因为它不仅可以隐藏数据还可以隐藏实现细节。开闭原则强调一个类不仅要防止外部影响(就像很多时候我们做的那样,标示很多方法为private),并且也要防止内部的干扰。内部干扰可以是任何熟知类内部结构的东西,像子类(which are in a much more powerful position to modify the behavior of a class).
    一个遵循开闭原则(Open-Closed Principle)的设计良好的类(well-designed)认为子类存在潜在的伤害(harmful),这也就是为什么你会看到很多方法都是final的。 没有了final的修饰符,子类可以覆写父类的任何非private的方法。方法的覆写存在着非常大的潜在伤害,因为它可能忽略或者改变类原来的实现意图。任何方法的重新定义都可能影响到父类与系统之间的契约(contract),导致潜在的逻辑混乱。
    但是你可以说你覆写方法的时候,可以简单的调用super.doMethod()来保证原来方法的逻辑运行(从而保证原来的方法定义),这个恰恰就是问题的症结之所在,就像没有任何的办法来保证覆写方法时一定会调用super.doMethod(). 还有,方法到底是应该在覆写代码的前面还是后面调用呢?这种不确定性对意图在不同系统中使用的lib来说,是不可接受的。
    无论如何,一个lib库如果想要被广泛的时候的话,就必须允许个性化的需求,也就是对扩展开放(open for extension).如果允许类的行为改变,你就应该允许类被扩展。扩展一般都是定义好得回调方法(callback methods)(在Spring中默认命名为为onXxx()). 这些回调(callback)方法意图就是被覆写(overridden),因为它们没有触及类的核心逻辑代码,因为所有的核心逻辑方法都被标记上final了。它会掉用一个或者更多的扩展方法来允许子类增加额外的行为。
    为了更好的说明这个原则,我们来看一下Controller接口的高层次的实现就是org.springframework.web.servlet.mvc.AbstractController. 这个类是Controller在高层次(类的继承机构)上的一个简单实现,无论如何,它提供了一个很好的开闭原则的例子,并且提供了一个学习Controoller的很好的切入点。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
3)A digital clock consists of a screen to display the time and a dial for setting in turn the year, month, day, hour and minute. Twisting the dial to the left reduces by one the value being changed but twisting it to the right increases it by one. Pushing the dial alters which value is being adjusted. At first, it is the year but after the dial is pushed once, it is the month, then after the dial is pushed again, it is the day and so on. Imagine the clock is represented by a class with attributes year, month, day etc. The following is what the code for a method rotateDialLeft() might look like. public void rotateDialLeft() { if (mode == YEAR_MODE) { year--; } else if (mode == MONTH_MODE) { month--; } else if (mode == DAY_MODE) { day--; } else if (mode == HOUR_MODE) { hour--; } else if (mode == MINUTE_MODE) { minute--; } } The code for rotateDialRight() is similar. Apply the Open-Closed Principle to explain why the above code is unsatisfactory from the design viewpoint, considering the possibility of future change to the code, giving an example of such a change. 5)Give the code required for the classes introduced in question 3), focusing on the code for a method selectState() which changes the value that is being adjusted from years to months. Make it clear in which classes the code is to be found. Assume the existence of other methods that are needed such as getMonthSetUpState(). 8)Suppose that in a multiplayer role-playing game, a class Client has a dependency to an interface Fighter with public methods attack(), defend() and escape(). The game designer now wishes for Client to use a class Wizard with three different but equivalent public methods castDestructionSpell(), shield() and portal(). Explain how it is possible to do this using an appropriate design pattern.
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值