惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
小众软件
小众软件
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
Jina AI
Jina AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Y
Y Combinator Blog
V
Visual Studio Blog
C
Check Point Blog
阮一峰的网络日志
阮一峰的网络日志
U
Unit 42
量子位
人人都是产品经理
人人都是产品经理
博客园 - 聂微东
M
MIT News - Artificial intelligence
爱范儿
爱范儿
B
Blog RSS Feed
MyScale Blog
MyScale Blog
H
Help Net Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
美团技术团队
L
LangChain Blog
D
Docker

博客园 - Charly

我的电影记录 再去听他的演唱会 学友12月29日广州演唱会 张学友十大粤语&十大国语金曲赏析 妈妈的第二次重生 随便谈谈最近参与的2个项目 中奖的幸运与不幸 设计模式学习笔记二十五——总结 Moss2007搜索服务配置,没有索引器和搜索配置页面报错问题解决 设计模式学习笔记二十四——Visitor模式 设计模式学习笔记二十二——Strategy模式 设计模式学习笔记二十一——State模式 设计模式学习笔记二十——Memento模式 设计模式学习笔记十九——Observer模式 在MOSS 2007中调试WebPart 设计模式学习笔记十八——Mediator模式 设计模式学习笔记十七——Iterator模式 设计模式学习笔记十六——Interpreter模式 设计模式学习笔记十五——Command模式
设计模式学习笔记二十三——TemplateMethod模式
Charly · 2007-08-24 · via 博客园 - Charly

动机:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。本模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

场景:以最近开发的一个WebPart为例,实现能以当前站点和任一站点列表库作为数据源显示前几条数据的列表WebPart(此处仅考虑普通列表库和文档库,至于其他库可通过子类扩展)。定义BaseDataListWebPart作为列表WebPart基类,TopDataListWebPart作为前几条数据列表WebPart类(以当前站点为数据源),ExtendDataSourceTopDataListWebPart类则以任意站点列表库为数据源显示前几条数据列表。目前该代码已满足项目需要,由于时间太紧,就凑合着用了。等项目结束,再整理下,把所有的列表库都考虑进去,包括图片库等。

结构
TemplateMethod模式结构图

代码

namespace DesignPattern.TemplateMethod
{
    
/// <summary>
    
/// 数据列表WebPart基类
    
/// </summary>

    public class BaseDataListWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    
{
        
/// <summary>
        
/// 获取当前数据列表
        
/// 子方法扩展点
        
/// </summary>

        public virtual SPList GetCurrentList()
        
{
            
//.
        }


        
/// <summary>
        
/// 获取当前数据记录
        
/// 模板方法
        
/// </summary>

        protected virtual SPListItemCollection GetListItems()
        
{
            SPList dataSourceList 
= GetCurrentList();
            
//.
        }


        
/// <summary>
        
/// 获取普通列表和文档列表数据项查看地址
        
/// 普通列表数据项查看地址从“列表库配置”列表读取,文档列表地址从文档列表地址读取
        
/// 子方法扩展点
        
/// </summary>
        
/// <returns></returns>

        protected virtual string GetItemViewUrl(SPItem item)
        
{
            
//.
        }

    }

}

namespace DesignPattern.TemplateMethod
{
    
/// <summary>
    
/// 前几条数据列表WebPart,以当前站点列表作为数据源
    
/// </summary>

    public class TopDataListWebPart : BaseDataListWebPart
    
{
        
/// <summary>
        
/// 获取当前数据列表
        
/// 重写实现扩展
        
/// </summary>

        public override SPList GetCurrentList()
        
{
            
//..
        }


        
/// <summary>
        
/// 模板方法,通过子类重写GetListItems和GetItemViewUrl实现扩展
        
/// </summary>

        protected override void Render(HtmlTextWriter writer)
        
{
            
try
            
{
                SPListItemCollection listItems 
= GetListItems();
                
if (listItems.Count > 0)
                
{
                    
foreach (SPItem item in listItems)
                    
{
                        
string itemViewUrl = GetItemViewUrl(item);
                        
//.
                    }

                    
//.
                }

                
else
                
{
                    
//.
                }

            }

            
catch (Exception e)
            
{
                writer.Write(e.Message);
            }

        }

    }

}

namespace DesignPattern.TemplateMethod
{
    
/// <summary>
    
/// 扩展TopDataListWebPart,实现可使用外部站点列表作为数据源
    
/// </summary>

    public class ExtendDataSourceTopDataListWebPart : TopDataListWebPart
    
{
        
/// <summary>
        
/// 获取当前数据列表
        
/// 重写实现扩展
        
/// </summary>

        public override SPList GetCurrentList()
        
{
            
//.
        }


        
/// <summary>
        
/// 获取当前列表数据记录
        
/// 重写实现扩展
        
/// </summary>

        protected override SPListItemCollection GetListItems()
        
{
            SPList dataSourceList 
= GetCurrentList();
            
//.
        }

    }

}

要点
        1、本模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
        2、除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是本模式的典型应用。
        3、在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法,纯虚方法),但一般推荐将它们设置为protected方法。