电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

老生常谈:策略模式


发布日期:2019/10/15
 

本来园子里面已经有很多特别好的关于设计模式学习的文章但一般都是概念性的或者都是些简单实例没有用过设计模式的朋友看过之后虽然明白怎么回事了但是对于自己实际项目中何时用设计模式就不太清楚了本人借jillzhang开发的控件中的部分代码与大家讨论下模式在具体项目中的应用好的代码应该与大家分享

名词解释:

策略:

:战略(学)

:策略 计谋 作战方针; 智谋 手腕

从策略一词来看策略模式是种倾向于行为的模式有点类似找仗时的做战方案一般司令员在做战前都会根据实际情况做出几套不同的方案如果当时情况有变就会根据相应的条件来判定用哪一套方案来替换原定方案但无论如何替换替换多少次仗还是要打的

在他的文章中给GRIDVIEW添加上数据导出成EXCELWORDPDF文件的功能这三类导出虽然具体操作略有不同但是大部分都相同

具体策略模式的类图:

策略模式定义(GOF):

策略模式:主要是定义一系列的算法把这些算法一个个封装成拥有共同接口的类它们之间可以互换使客户端调用它们的时候能够互不影响地变化

具体代码如下

第一数据导出的接口类:IExporter

抽象策略(Strategy)角色这是一个抽象角色通常由一个接口或抽象类实现此角色给出所有的具体策略类所需的接口

Code

/**////<summary>

///将GridView导出到其他文件的接口

///</summary>

publicinterfaceIExporter

{

/**////<summary>

///输出编码

///</summary>

EncodingResponseEncoding{get;}

/**////<summary>

///导出文件的名称

///</summary>

stringExportFileName{get;}

/**////<summary>

///将GirdView导出为其他格式的文件

///</summary>

///<paramname=grid>要导出的GridView对象</param>

///<paramname=unExportedColumnNames>不导出的列名称集合</param>

voidExport(GridViewExgrid);

}

下面为实现了此接口的抽象类

Code

publicabstractclassExporter:IExporter

{

privatefields#regionprivatefields

Encoding_responseEncoding;

string_exportFileName;

#endregion

myconstructors#regionmyconstructors

publicExporter(EncodingencodingstringoutName)

{

this_responseEncoding=encoding;

this_exportFileName=outName;

}

#endregion

publicproperty#regionpublicproperty

/**////<summary>

///输出编码

///</summary>

publicEncodingResponseEncoding

{

get

{

return_responseEncoding;

}

}

/**////<summary>

///导出文件的名称

///</summary>

publicstringExportFileName

{

get

{

return_exportFileName;

}

}

#endregion

publicmethods#regionpublicmethods

/**////<summary>

///将GirdView导出为其他格式的文件

///</summary>

///<paramname=grid>要导出的GridView对象</param>

///<paramname=unExportedColumnNames>不导出的列名称集合</param>

publicabstractvoidExport(GridViewExgrid);

#endregion

privatemethods#regionprivatemethods

protectedstringReplaceHref(stringhtml)

{

stringcontent=RegexReplace(html(<a[^>]+>)|(</a>));

returncontent;

}

protectedvirtualvoidExport(GridViewExgridstringextensionstringcontentType)

{

//具体代码略

}

#endregion

}

第二context

环境(Context)角色持有一个Strategy类的引用

Code

DropDownListdrop=dropList;

if(drop!=null)

{

if(dropSelectedIndex>)

{

switch(dropSelectedValue)

{

caseExcel:

{

IExporterexporter=newExcelExporter(EncodingGetEncoding(gb)this_exportFileName);

ExporterHelperExport(Ownerexporter);

break;

}

caseWord:

{

IExporterexporter=newWordExporter(EncodingGetEncoding(gb)this_exportFileName);

ExporterHelperExport(Ownerexporter);

break;

}

casePdf:

{

IExporterexporter=newPdfExporter(EncodingGetEncoding(gb)this_exportFileName);

ExporterHelperExport(Ownerexporter);

break;

}

}

}

}

[nextpate]

第三具体实现类

具体策略(ConcreteStrategy)角色包装了相关的算法或行为

下面是三个具体操作类

Code

/**////<summary>

///Excel导出

///</summary>

publicclassExcelExporter:Exporter

{

privatefields#regionprivatefields

staticreadonlystringextension=xls;

staticreadonlystringcontentType=application/vndxls;

#endregion

myconstructors#regionmyconstructors

publicExcelExporter(EncodingencodingstringoutName):base(encodingoutName)

{

}

#endregion

publicmethods#regionpublicmethods

/**////<summary>

///将GirdView导出为其他格式的文件

///</summary>

///<paramname=grid>要导出的GridView对象</param>

///<paramname=unExportedColumnNames>不导出的列名称集合</param>

publicoverridevoidExport(GridViewExgrid)

{

Export(gridextensioncontentType);

}

#endregion

PdfExporter:

Code

publicclassPdfExporter:Exporter

{

staticreadonlystringextension=pdf;

staticreadonlystringcontentType=application/pdf;

publicPdfExporter(EncodingencodingstringoutName)

:base(encodingoutName)

{

}

publicoverridevoidExport(GridViewExgrid)

{

//具体代码略

}

}

WordExporter:

Code

/**////<summary>

///Word导出

///</summary>

publicclassWordExporter:Exporter

{

privatefields#regionprivatefields

staticreadonlystringextension=doc;

staticreadonlystringcontentType=application/msword;

#endregion

myconstructors#regionmyconstructors

publicWordExporter(EncodingencodingstringoutName)

:base(encodingoutName)

{

}

#endregion

publicmethods#regionpublicmethods

/**////<summary>

///将GirdView导出为其他格式的文件

///</summary>

///<paramname=grid>要导出的GridView对象</param>

///<paramname=unExportedColumnNames>不导出的列名称集合</param>

publicoverridevoidExport(GridViewExgrid)

{

Export(gridextensioncontentType);

}

#endregion

}

策略模式优点

算法的使用和算法本身解耦即把变化的具体算法封装了起来策略模式是除了继承之外的一种弹性替代方案如果你使用继承定义了一个类下面有部分的派生类此时你会让基类所困住要想修改它特别不容易而策略模式则可能通过组合不同的对象来改变行为

策略模式缺点

虽说客户代码无须关心各个策略是如何实现的但是它们还是要知道有多少种策略实现具体功能情况这样才可以根据需要使用哪个策略

使用策略模式后出现很多小类

总结

设计模式的有效应用能够给我们的开发带来效率同时也是把双刃剑滥用设计模式往往会费力不计好本人在实际开发中对于模式的应用还不是特别多如果有什么地方说错了还望大家谅解

上一篇:业务系统设计之系统菜单设计

下一篇:DataTable.NewRow 内存洩漏问题