设计模式-模板方法模式

设计模式-模板方法模式

定义:一个抽象类公开定义了执行它的方法的方式/模板,而一些特殊方法的实现可以在子类中重写实现,但调用将以抽象类中定义的方式进行。

模板方法使得子类在不改变一个方法的结构前提下,重新定义该方法内部调用的一些方法,来得到一个新的执行结果。

如简历模板、论文模板,下载一个模板后不需要修改模块的位置,按顺序将自己的内容填写到相应的模块中,最终每个人都能制作出来一个属于自己的独一无二的简历、论文等。

依然以汽车为例,现在奔驰小轿车和宝马小轿车都生产好了,开始测试行驶
虽然轿车品牌不同,但是行驶测试的方式都是大同小异的,驾驶员测试步骤如下
(1) 补充燃料
(2) 检查车辆周围是否有障碍物
(3) 调整座椅
(4) 调整后视镜
(5) 调整方向盘
(6) 启动发动机
(7) 检查车灯
(8) 挂挡起步

由于车辆设计不同,奔驰和宝马车的一些细节操作可能有所不同,奔驰车的档位和座椅的使用比较特殊,宝马的方向盘调整比较特殊。

下面定义一个驾驶员模板基类,在模板基类的 DrivingTest 方法中固定了测试方法顺序,不能修改
一个奔驰驾驶员、一个宝马驾驶员 分别继承 驾驶员模板基类,根据自己的需求重写基类中可以重写的方法。

驾驶员模板基类

    // 驾驶员基类
    public abstract class DriverTemplate
    {
        // 补充燃料
        protected virtual void Refuel()
        {
            Console.WriteLine("补充燃料");
        }

        // 车周围障碍物检查
        protected virtual void Obstacle()
        {
            Console.WriteLine("车周围障碍物检查");
        }

        // 调整座椅
        protected virtual void AdjustSeat()
        {
            Console.WriteLine("调整座椅");
        }

        // 调整后视镜
        protected virtual void AdjustRearviewMirror()
        {
            Console.WriteLine("调整后视镜");
        }

        // 调整方向盘
        protected virtual void AdjustSteeringWheel()
        {
            Console.WriteLine("调整方向盘");
        }

        // 启动发动机
        protected virtual void StartTheEngine()
        {
            Console.WriteLine("启动发动机");
        }

        // 检查车灯
        protected virtual void CheckLamp()
        {
            Console.WriteLine("检查车灯");
        }

        // 挂挡起步
        protected virtual void StartsGear()
        {
            Console.WriteLine("挂挡起步");
        }

        // 行驶测试,固定逻辑,不允许子类重写
        public void DrivingTest()
        {
            // 补充燃料
            Refuel();

            // 车周围障碍物检查
            Obstacle();

            // 调整座椅
            AdjustSeat();

            // 调整后视镜
            AdjustRearviewMirror();

            // 调整方向盘
            AdjustSteeringWheel();

            // 启动发动机
            StartTheEngine();

            // 检查车灯
            CheckLamp();

            // 挂挡起步
            StartsGear();
        }
    }

奔驰驾驶员

    // 奔驰驾驶员
    public class BenzDriver : DriverTemplate
    {
        // 奔驰座椅调整比较特殊,子类中重写该方法
        protected override void AdjustSeat()
        {
            Console.WriteLine("奔驰的座椅调整方式");
        }

        // 奔驰的档位比较特殊,子类中重写改方法
        protected override void StartsGear()
        {
            Console.WriteLine("奔驰的档位操作方式 \n");
        }
    }

宝马驾驶员

    // 宝马驾驶员
    public class BMWDriver : DriverTemplate
    {
        // 宝马的方向盘调整比较特殊,子类中重写该方法
        protected override void AdjustSteeringWheel()
        {
            Console.WriteLine("宝马的方向盘调整方式");
        }
    }

代码调用如下


    class Customer
    {
        public Customer()
        {
            BenzDriver benzDriver = new BenzDriver();
            benzDriver.DrivingTest();

            BMWDriver bMWDriver = new BMWDriver();
            bMWDriver.DrivingTest();
        }
    }

在这里插入图片描述

优点:
(1) 实现了代码复用,封装了不变部分,扩展可变部分。
(2) 灵活应对子类的变化,符合开闭原则。
(3) 提取公共部分代码,便于维护。

缺点
(1) 引入了抽象类,如果具体实现过多,需要开发人员花费更多的时间去理清类之间的关系。
(2) 抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响,增加了阅读难度。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值