模板方法模式定义一个操作中的算法的骨架,而将步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。模板方法模式是由子类决定实现算法中的步骤,工厂方法由子类决定实现哪一个具体的类,策略模式是封装可以互换的行为,使用委托决定采用哪一个行为,有的时候这三种容易出现理解上的偏差。
模板方法的UML类图:
关于模板方法我们思考一个生活中的例子,我们都会网购,天猫或者京东,经历一下四个步骤,①访问网站②浏览下单③支付④收货,两种网站第二步和最后一步都是一样的,访问和支付的访问不一样,两个网站网址不一样,支付方式不一样~稍微思考一下可以怎么实现~
关于上面的需要设计三个类,网购类,天猫类,京东类:
OnLineShop:
@protocol OnLineShopProtocol @optional -(void)accessURL; @optional -(void)pay; @end @interface OnLineShop : NSObject<OnLineShopProtocol> -(void)shop; -(Boolean)callMyMobileHook; @end
@interface OnLineShop() -(void)createOrder; -(void)receiptGoods; @end @implementation OnLineShop -(void)shop{ [self accessURL]; [self createOrder]; [self pay]; if ([self callMyMobileHook]) { [self receiptGoods]; } } -(void)createOrder{ NSLog(@"创建订单成功"); } -(void)receiptGoods{ NSLog(@"收到了物品"); } //子类可以回调钩子 -(Boolean)callMyMobileHook{ return true; } @end
Tmall类继承自OnLineShop:
@implementation Tmall -(void)accessURL{ NSLog(@"https://www.taobao.com/"); } -(void)pay{ NSLog(@"支付宝"); } -(Boolean)callMyMobileHook{ return true; } @end
JDong类:
@implementation JDong -(void)accessURL{ NSLog(@"http://www.jd.com/"); } -(void)pay{ NSLog(@"货到付款"); } -(Boolean)callMyMobileHook{ NSLog(@"博客园-FlyElephant"); return false; } @end
代码测试:
OnLineShop *tmall=[[Tmall alloc]init]; [tmall shop]; OnLineShop *jd=[[JDong alloc]init]; [jd shop];
测试结果:
模板方法优点:
①模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。
②子类实现算法的某些细节,有助于算法的扩展。通过一个父类调用子类实现的操作,
③通过子类扩展增加新的行为,符合“开放-封闭原则”。
缺点
①每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。
适用于在某些类的算法中,用了相同的方法,造成代码的重复。 控制子类扩展,子类必须遵守算法规则。
模板方式中涉及到一个原则是好莱坞原则,别调用我们,我们会调用你~理解起来就是高层组件可以调用底层组件,底层组件不要调用高层组件~