C#:抽象策略基类用作策略对象的抽象工厂 [英] C#: Abstract Strategy base class serving as Abstract Factory for Strategy objects

查看:94
本文介绍了C#:抽象策略基类用作策略对象的抽象工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的公司创建一个基于Web的工具,实质上是使用地理输入来产生表格结果.当前,三个不同的业务领域使用我的工具并收到三种不同类型的输出.幸运的是,所有输出都基于主表-子表的相同思想,甚至共享一个共同的主表.

I am trying to create a web-based tool for my company that, in essence, uses geographic input to produce tabular results. Currently, three different business areas use my tool and receive three different kinds of output. Luckily, all of the outputs are based on the same idea of Master Table - Child Table, and they even share a common Master Table.

不幸的是,在每种情况下,子表的相关行都包含非常不同的数据.因为这是唯一的争用点,所以我将FetchChildData方法提取到名为DetailFinder的单独的类中.结果,我的代码如下所示:

Unfortunately, in each case the related rows of the Child Table contain vastly different data. Because this is the only point of contention I extracted a FetchChildData method into a separate class called DetailFinder. As a result, my code looks like this:

DetailFinder DetailHandler;
if (ReportType == "Planning")
  DetailHandler = new PlanningFinder();
else if (ReportType == "Operations")
  DetailHandler = new OperationsFinder();
else if (ReportType == "Maintenance")
  DetailHandler = new MaintenanceFinder();
DataTable ChildTable = DetailHandler.FetchChildData(Master);

PlanningFinder,OperationsFinder和MaintenanceFinder都是DetailFinder的子类.

Where PlanningFinder, OperationsFinder, and MaintenanceFinder are all subclasses of DetailFinder.

我刚刚被要求增加对另一个业务领域的支持,但我不希望继续这种if封锁趋势.我希望有一个如下所示的解析方法:

I have just been asked to add support for another business area and would hate to continue this if block trend. What I would prefer is to have a parse method that would look like this:

DetailFinder DetailHandler = DetailFinder.Parse(ReportType);

但是,我不知道如何让DetailFinder知道哪个子类处理每个字符串,甚至存在什么子类,而不仅仅是将if块移至Parse方法.子类是否可以使用抽象的DetailFinder注册自己?

However, I am at a loss as to how to have DetailFinder know what subclass handles each string, or even what subclasses exist without just shifting the if block to the Parse method. Is there a way for subclasses to register themselves with the abstract DetailFinder?

推荐答案

您可能希望使用类型映射到创建方法:

You might want to use a map of types to creational methods:

public class  DetailFinder
{
    private static Dictionary<string,Func<DetailFinder>> Creators;

    static DetailFinder()
    {
         Creators = new Dictionary<string,Func<DetailFinder>>();
         Creators.Add( "Planning", CreatePlanningFinder );
         Creators.Add( "Operations", CreateOperationsFinder );
         ...
    }

    public static DetailFinder Create( string type )
    {
         return Creators[type].Invoke();
    }

    private static DetailFinder CreatePlanningFinder()
    {
        return new PlanningFinder();
    }

    private static DetailFinder CreateOperationsFinder()
    {
        return new OperationsFinder();
    }

    ...

}

用作:

DetailFinder detailHandler = DetailFinder.Create( ReportType );

我不确定这是否比您的if语句好得多,但是它确实使读取和扩展变得异常容易.只需在Creators映射中添加一个创建方法和一个条目即可.

I'm not sure this is much better than your if statement, but it does make it trivially easy to both read and extend. Simply add a creational method and an entry in the Creators map.

另一种替代方法是存储报表类型和查找器类型的映射,然后如果总是要调用构造函数,则在该类型上使用Activator.CreateInstance.如果创建对象的复杂性更高,则上面的工厂方法详细信息可能更合适.

Another alternative would be to store a map of report types and finder types, then use Activator.CreateInstance on the type if you are always simply going to invoke the constructor. The factory method detail above would probably be more appropriate if there were more complexity in the creation of the object.

public class DetailFinder
{
      private static Dictionary<string,Type> Creators;

      static DetailFinder()
      {
           Creators = new Dictionary<string,Type>();
           Creators.Add( "Planning", typeof(PlanningFinder) );
           ...
      }

      public static DetailFinder Create( string type )
      {
           Type t = Creators[type];
           return Activator.CreateInstance(t) as DetailFinder;
      }
}

这篇关于C#:抽象策略基类用作策略对象的抽象工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆