3.模板方法模式与控制反转
“不要给我们打电话,我们会给你打电话”这是著名的好莱坞原则。在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。模板方法模式充分的体现了“好莱坞”原则。由父类完全控制着子类的逻辑,这就是控制反转。子类可以实现父类的可变部份,却继承父类的逻辑,不能改变业务逻辑。
4.模板方法模式与开闭原则
什么是“开闭原则”?
开闭原则是指一个软件实体应该对扩展开放,对修改关闭。
也就是说软件实体必须是在不被修改的情况下被扩展。模板方法模式意图是由抽象父类控制优异逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用,同时也遵守了开闭原则。
父类通过优异逻辑,它通过定义并提供一个具体方法来实现,我们也称之为模板方法。通常这个模板方法才是外部对象最关心的方法。在上面的订单处理例子中,public Order placeOrder(int customerId , List orderItemList) 这个方法才是外部对象最关心的方法。所以它必须是public的,才能被外部对象所调用。
子类需要继承父类去扩展父类的基本方法,但是它也可以覆写父类的方法。如果子类去覆写了父类的模板方法,从而改变了父类控制的优异逻辑,这违反了“开闭原则”。我们在使用模板方法模式时,应该总是保证子类有正确的逻辑。所以模板方法应该定义为final的。所以AbstractOrder 类的模板方法placeOrder方法应该定义为final。
public final Order placeOrder(int customerId , List orderItemList)
因为子类不能覆写一个被定义为final的方法。从而保证了子类的逻辑永远由父类所控制。
注意 :模板方法模式中,抽象类的模板方法应该声明为final的。
5.模板方法模式与对象的封装性
面向对象的三大特性:继承,封装,多态。
对象有内部状态和外部的行为。封装是为了信息隐藏,通过封装来维护对象内部数据的完整性。使得外部对象不能够直接访问一个对象的内部状态,而必须通过恰当的方法才能访问。
在Java语言中,采用给对象属性和方法赋予指定的修改符(public、protected、private)来达到封装的目的,使得数据不被外部对象恶意的访问及方法不被错误调用导造成破坏对象的封装性。
降低方法的访问级别,也就是最大化的降低方法的可见度是一种很重要的封装手段。最大化降低方法的可见度除了可以达到信息隐藏外,还能有效的降低类之间的耦合度,降低一个类的复杂度。还可以减少开发人员发生的的错误调用。
一个类应该只公开外部需要调用的方法。而所有为public方法服务的方法都应该声明为protected或private。如是一个方法不是需要对外公开的,但是它需要被子类进行扩展的或调用。那么把它定义为protected.否则应该为private。
显而易见,模板方法模式中的声明为abstract的基本操作都是需要迫使子类去实现的,它们仅仅是为模板方法placeOrder服务的。它们不应该被AbstractOrder所公开,所以它们应该protected。
注意 : 板方法模式中,迫使子类实现的抽象方法应该声明为protected abstract。protected abstract int getOrderItemPrice(OrderItem orderItem); protected abstract int getSpendingLimit(int customerId); protected abstract int saveOrder(int customerId, int total, List orderItemList);