苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper万能框架(V2.3-含.netcore) HttpHelper官方出品,无敌框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 最牛的爬虫类,没有爬不到只有想不到 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 1187|回复: 5

[学习心得] C#模板模式介绍

[复制链接]
发表于 2019-1-15 14:40:19 | 显示全部楼层 |阅读模式
本帖最后由 惜 于 2019-1-15 15:23 编辑

一 、  模板方法 (Template Method ) 模式


      准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩
余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模版方法
模式的用意。

      很多人可能没有想到,模版方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模版
方法模式而没有意识到自己已经使用了这个模式。模版方法模式是基于继承的代码复用的基本技术,模版方法模
式的结构和用法也是面向对象设计的核心。

      模版方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另
一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法(primitive
method);而将这些基本法方法总汇起来的方法叫做模版方法(template method),这个设计模式的名字
就是从此而来。

二 、  模版方法模式的结构

模版方法模式的静态结构如下图所示。
1.png
这里涉及到两个角色:

 抽象模版(AbstractClass)角色有如下的责任:

      定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。
定义并实现了一个模版方法。这个模版方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成
步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

 具体模版(ConcreteClass)角色有如下的责任:

      实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。
每一个抽象模版角色都可以有任意多个具体模版角色与之对应,而每一个具体模版角色都可以给出这些抽象方法
(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

三 、  模板方法模式的 示意性代码

[C#] 纯文本查看 复制代码
using System;

namespace ConsoleApplication1
{
// "AbstractClass"
    abstract class AbstractClass
    {
        // Methods
        public abstract void PrimitiveOperation1();
        public abstract void PrimitiveOperation2();
        // The Template method
        public void TemplateMethod()
        {
            Console.WriteLine("In AbstractClass.TemplateMethod()");
            PrimitiveOperation1();
            PrimitiveOperation2();
        }
    }
// "ConcreteClass"
    class ConcreteClass : AbstractClass
    {
        // Methods
        public override void PrimitiveOperation1()
        {
            Console.WriteLine("Called ConcreteClass.PrimitiveOperation1()");
        }
        public override void PrimitiveOperation2()
        {
            Console.WriteLine("Called ConcreteClass.PrimitiveOperation2()");
        }
    }
    /// <summary>
    /// Client test
    /// </summary>
    public class Client
    {
        public static void Main(string[] args)
        {
            // Create instance and call template method
            ConcreteClass c = new ConcreteClass();
            c.TemplateMethod();
        }
    }
}



四 、  继承作为复用的工具

使用继承作为复用的手段必须慎重,C#语言的设计师对使用继承作为复用的工具有着不同层次上的认识。

不知其一

首先,初学 C#的程序员可能不知道什么是继承,或者认为"继承"是高深的工具。那时候,大部分的功能复用都
是通过委派进行的。

知其一、不知其二

      然后慢慢地,他们发现在 C#语言里实现继承并不困难,并且初步认识到继承可以使子类一下子得到基类的行为。
这时他们就会跃跃欲试了,试图使用继承作为功能复用的主要工具,并把原来应当使用委派的地方,改为使用继
承,这时继承就有被滥用的危险。

知其二

      很多面向对象的设计专家从 1986 年就开始警告继承关系被滥用的可能。有一些面向对象的编程语言,如 SELF
语言,甚至将类的继承关系从语言的功能中取消掉,改为完全使用委派。

      其他的设计师虽然不提倡彻底取消继承,但无一例外地鼓励在设计中尽可能使甩委派关系代替继承关系。比如在
【GOF95】一书中,状态模式、策略模式、装饰模式、桥梁模式以及抽象工厂模式均是将依赖于继承的实现转
换为基于对象的组合和聚合的实现,这些模式的要点就是使用委派关系代替继承关系。

知其三

      是不是继承就根本不该使用呢?事实上对数据的抽象化、继承、封装和多态性并称 C#和其他绝大多数的面向对
象语言的几项最重要的特性。继承不应当被滥用,并不意味着继承根本就不该使用。因为继承容易被滥用就彻底
抛弃继承,无异于因噎废食。

      继承使得类型的等级结构易于理解、维护和扩展,而类型的等级结构非常适合于抽象化的设计、实现和复用。尽
管【GOF95】所给出的设计模式基本上没有太多基于继承的模式,很多模式都是用继承的办法定义、实现接口
的。多数的设计模式都描写一个以抽象类作为基类,以具体类作为实现的等级结构,比如适配器模式、合成模式、
桥梁模式、状态模式等。

      模版方法模式则更进了一步:此模式鼓励恰当地使用继承。此模式可以用来改写一些拥有相同功能的相关的类,
将可复用的一般性的行为代码移到基类里面,而把特殊化的行为代码移到子类里面。
因此,熟悉模版方法模式便成为一个重新学习继承的好地方。

发表于 2019-1-15 14:56:41 | 显示全部楼层
发表于 2019-1-15 15:01:24 | 显示全部楼层
发表于 2019-1-15 15:11:57 | 显示全部楼层
发表于 2019-1-15 15:21:36 | 显示全部楼层
发表于 2019-1-15 15:32:20 | 显示全部楼层
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备17001017号-1)

GMT+8, 2019-12-7 23:05

© 2017-2018

快速回复 返回顶部 返回列表