.Net中之设计模式——Strategy模式

.Net中之设计模式——Strategy模式

相同、模式概述

“面向接口编程”是面向对象编程思想被极度重点的一个规格。根据“封装变化”的原理,我们经常以好变动的片段进行抽象,定义也接口。对于调用者而言,只需要理解接口的外表定义即可,具体的实现则毫不理会。在设计模式中,Strategy模式就是这般的一个“面向接口编程”的超级体现,它进行抽象的同等有的是本着一定的“算法”,或者说是“策略”。
若我们要支付一个税务系统,那么关于税务的算计就会按部就班纳税人之异而分为个人所得税和企业所得税,而及时点儿栽税收项目依法应交的税收在计算办法上是大相径庭不同之简单种植政策。此时,我们尽管可以用策略模式,将税收政策抽象为接口ITaxStrategy:
public interface ITaxStrategy
{
     double Calculate(double income);
}
每当针对税收计算策略形成了纸上谈兵后,就打统筹上去除了模块间存在的耦合,消除了变通或许会见导致的前景系统的泛修改,而所谓“面向接口编程”正是根据这样的理。
概念接口之后,各种税收政策均落实该接口:
public class PeronalTaxStrategy:ITaxStrategy
{
public double Calculate(double income)
    {
     //实现略;
    }
}
public class EnterpriseTaxStrategy:ITaxStrategy
{
public double Calculate(double income)
    {
     //实现略;
    }
}
设此刻起一个官的类似,提供税收的连锁操作,其中即连计算所得税的办法:
public class TaxOp
{
private ITaxStrategy m_strategy;
    public TaxOp(ITaxStrategy strategy)
    {
     this.m_strategy = strategy;
    }
    public double GetTax(double income)
{
     return strategy.Calculate(income);
    }
}
在这个仿佛中,接收了一个ITaxStrategy类型的目标,由于拖欠目标是一个接口类型,因此类TaxOp是暨实际税收政策无关之,它们之间以接口的引入而改为了一个弱依赖的干,如类图所示:
 Oracle 1
假使客户端要调用有关税收的操作时,就好根据纳税人之花色具体实例化税收政策对象:
public class App
{
    public static void Main(string[] args)
{
     TaxOp op = new TaxOp(new PersonalTaxStrategy());
     Console.WriteLine(“The Personal Tax is :{0}”, op.GetTax(1000));
}
}

二、.Net Framework中的Strategy模式

Stragety模式的采取极为广阔,在.Net
Framework中自然不乏用之例证。例如在.Net中,为集聚类型Array和ArrayList提供的排序功能,其促成中就动了Strategy模式。它是针对性比较算法进行了打包,定义了IComparer接口。实现IComparer接口的近乎,可以是逐一,也足以是逆序的比较简单个对象的高低。
另外,在System.Configuration.Provider命名空间中,关于Provider的后续体系下便引入了很多Strategy模式的运用。在是命名空间下,主要是概念了一个虚幻类ProviderBase,它的概念较为简单,仅仅包括一个初始化的虚方法和几单虚属性,如下代码:
public abstract class ProviderBase
{
      // Methods
      protected ProviderBase();
      public virtual void Initialize(string name, NameValueCollection
config);

      // Properties
      public virtual string Description { get; }
      public virtual string Name { get; }

      // Fields
      private string _Description;
      private bool _Initialized;
      private string _name;
}
ProviderBase的派生类比较多,包括发生System.Configuration.ProtectedConfigurationProvider、System.Configuration.SettingProvider、System.Web.Security.RoleProvider、System.Web.Security.MembershipProvider等,不过这些派生子类都是抽象类,它们而从生个别的接续体系,且以所有了Strategy模式的特征。以RoleProvider为条例,首先,我们看看RoleProvider在.Net
Framework中之定义:
public abstract class RoleProvider : ProviderBase
{
      // Methods
      protected RoleProvider();
      public abstract void AddUsersToRoles(string[] usernames,
string[] roleNames);
      public abstract void CreateRole(string roleName);
      public abstract bool DeleteRole(string roleName, bool
throwOnPopulatedRole);
      public abstract string[] FindUsersInRole(string roleName, string
usernameToMatch);
      public abstract string[] GetAllRoles();
      public abstract string[] GetRolesForUser(string username);
      public abstract string[] GetUsersInRole(string roleName);
      public abstract bool IsUserInRole(string username, string
roleName);
      public abstract void RemoveUsersFromRoles(string[] usernames,
string[] roleNames);
      public abstract bool RoleExists(string roleName);

      // Properties
      public abstract string ApplicationName { get; set; }
}
于RoleProvider抽象类吃,没有切实可行的落实,均为架空方法,此时之虚幻类其实早已与接口无异(注:事实上,在WebLogic中,在针对角色管理之API中,就用RoleProvider定义为接口)。为了便利理解这里的规划思想,我们本着RoleProvider类进行简化,仅关注此类的CreateRole()抽象方法。
兑现RoleProvider抽象类的类别比较多,例如AuthorizationStoreRoleProvider、SqlRoleProvider、WindowsTokenRoleProvider等等。因此,最后之落实类图应该如下:
 Oracle 2
子类均再次写了父类RoleProvider的抽象方法,例如SqlRoleProvider:
public class SqlRoleProvider:RoleProvider
{
 public override void CreateRole(string roleName)
 {
  //实现略;
 }
}
每当ASP.NET中会用到RoleProvider,通常是当web.config配置文件对该展开部署,例如在RoleManager节中安排RoleProvider:
<roleManager defaultProvider=”SqlProvider” enabled=”true”>
    <providers>
       <add  name=”SqlProvider”
        type=”System.Web.Security.SqlRoleProvider”
        connectionStringName=”SqlServices”
        applicationName=”PatternsSample” />
    </providers>
</roleManager>
每当部署文件被,.Net内部的处理时,要求providers的花色必须是RoleProvider类型,然后经过安装type的价,使该以及具象的RoleProvider进行绑定。这里的惩处法明确以了Dependency
Injection(依赖注入)技术,利用反射技术以SqlRoleProvider对象sqlProvider注入,这样就避免了针对性SqlRoleProvider具体对象的缔造,解除了调用者与她里面的戏剧性。当然在配置文件被,RoleProvider还欲和Membership配合下,但这不是这里所要关注之要紧,因此不再详细讲解。
及RoleProvider相同的宏图方,在.Net
Framework中,MemberShipProvider同样利用了Strategy模式,如下图所出示之规划布局:
 Oracle 3
常用的凡现实性类SqlMembershipProvider,它也SQL
Server提供了Membership的保管。如果要是呢Membership提供对Oracle数据库的支撑,我们得打定义一个类继承MembershipProvider:
public class OracleMembershipProvider:MembershipProvider
{
 //实现略;
}
在.Net
Framework中,还有一个突出的Strategy模式的使用,就是接口IConfigurationSectionHandler:
public interface IConfigurationSectionHandler
{     
      object Create(object parent, object configContext, XmlNode
section);
}
欠接口中蕴含的方才来一个,就是Create()方法,我们可知晓也创建配置节的一个算法,而落实该接口的切近包括发生DictionarySectionHandler、IgnoreSectionHandler、NameValueSectionHandler等等,分别对应各种配置节的创办项目。此外,我们尚足以友善定义一个看似,来贯彻该接口,例如:
public class CustomHandler : IConfigurationSectionHandler
{
    public object Create(object parent, object configContext, XmlNode
section)
    {
       //实现略;
    }
}
自类图中,我们可以看,它杀吻合Strategy模式的表征:
 Oracle 4
尽管如此于.Net2.0丁,IConfigurationSectionHandler类型的对象就被ObsoleteAttribute设置也废除,而被ConfigurationSection的实现所代表,但这种计划思想依然是值得借鉴之。

相关文章