行为型模式之模板模式

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板.它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行.这种类型的设计模式属于行为型模式

使用模板方法要思考一下几点:

  • 在父类中一次性实现算法中不可变部分,并将可变的行为留给子类来实现
  • 子类公用的行为应该被提出来放到公共类中,以避免代码重发
  • 要考虑一些特殊情况特殊处理.这里采用子类的扩展来实现。可以定义一些在特定点调用“钩子”操作方法。子类可以通过对钩子操作的实现从而在这些点上扩展功能。钩子操作默认情况是不对整个模板造成影响的。子类重载后,才为模板算法提供附加的操作。比如项目中的某些数据请求方法要加请求头token之类,但其它大部分网络请求却不需要,就可以采用"钩子"操作来实现。

场景

比如,小时候老师布置作业都是说多少页第几题,抄写题目并答题,这样我们就需要先抄题目再做答案,有时候没看清或没听清把题目抄错了,这就意味着,即使我们做的再好,也不会正确
后来老师每次布置作业都是发试卷,这样的好处就是大家的题目是一样的,大家做答案就行了,这就是模板模式,题目一样,不同的是答案不一样

模式结构和说明

在这里插入图片描述

AbstractClass:抽象类.用来定义算法骨架和原语操作,具体的子类通过重定义这些原语操作来实现一个算法的各个步骤.在这个类里面,还可以提供算法中通用的实现
ConcreteClass:具体实现类.用来实现算法骨架中的某些步骤,完成跟特定子类相关的功能

示例代码

  1. 定义抽象类(模板)
@interface GTPaper : NSObject
/**/
@property (nonatomic,strong) NSString *answer;
//题目1
- (void)subject1;
//题目2
- (void)subject2;

@end
- (void)subject1
{
    NSLog(@"中国是世界%@ 人口大国\n A 第一 B 第二 C 第三 D 第四 ",self.answer);
}
- (void)subject2
{
    NSLog(@"刀削面是%@省的特色\n A 山东 B 山西  C 陕西  D 兰州",self.answer);
}
  1. 定义子类,完成特有功能
@implementation GTPagerA
- (void)subject1
{
    self.answer = @"A 第一";
    [super subject1];
}

- (void)subject2
{
    self.answer = @"A 山东";
    [super subject2];
}
@end
@implementation GTPagerB

- (void)subject1
{
    self.answer = @"A 第一";
    [super subject1];
}

- (void)subject2
{
    self.answer = @"B 山西";
    [super subject2];
}

@end

可以看出上面的子类只有答案是不同的
3. 客户端实践

    GTPaper *pageA = [GTPagerA new];
    [pageA subject1];
    [pageA subject2];
    
    GTPaper *pageB = [GTPagerB new];
    [pageB subject1];
    [pageB subject2];

在这里插入图片描述

模式讲解

1. 模式的功能

模板方法的功能在于固定算法骨架,而让具体算法实现可扩展。

模板方法还额外提供了一个好处,就是可以控制子类的扩展.因为在父类里面定义好了算法的步骤,只是在某几个固定的点才会调用到被子类实现的方法,因此也就只允许在这几个点来扩展功能,这些个可以被子类覆盖以扩展功能的方法通常被称为"钩子"方法

2. 变与不变

程序设计的一个很重要的思考点就是“变与不变”,也就是分析程序中哪些功能是可变的,哪些功能是不变的,然后把不变的部分抽象出来,进行公共的实现,把变化的部分分离出去,用接口来封装隔离,或者是用抽象类来约束子类行为。

模板方法模式很好的体现了这一点。模板类实现的就是不变的方法和算法的骨架,而需要变化的地方,都通过抽象方法,把具体实现延迟到子类去了,而且还通过父类的定义来约束了子类的行为,从而使系统能有更好的复用性和扩展性

讲到这大家再想想除了继承外,还有别的方式可以实现模式的思想吗?
答案肯定的有,那就是回调机制,先实现公共部分,然后在回调里实现不同的处理方式,从某一个方面而言,回调机制要比继承好,因为oc的继承是单继承的,对子类而言,使用继承方式,就不能继承其他对象了,并且回调机制是通过委托方式来实现功能的,耦合成都要比继承低,大家可以试试,这里不做过多代码实现

Demo地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值