当前位置: 首页 > 编程语言 > C#

抽象策略基类,用作策略对象的抽象工厂Share

时间:2023-04-10 15:12:28 C#

C#:抽象策略基类,用作策略对象的抽象工厂公司工具,本质上,它使用地理输入来生成表格结果。目前,三个不同的业务领域使用我的工具并获得三种不同的输出。幸运的是,所有输出都基于相同的主子表概念,甚至它们共享一个公共主表。不幸的是,在每种情况下,子表的相关行都包含非常不同的数据。由于这是唯一的争论点,我将FetchChildData方法提取到一个名为DetailFinder的单独类中。结果,我的代码如下所示:DetailFinderDetailHandler;if(ReportType=="Planning")DetailHandler=newPlanningFinder();elseif(ReportType=="Operations")DetailHandler=newOperationsFinder();elseif(ReportType=="Maintenance")DetailHandler=newMaintenanceFinder();DataTableChildTable=DetailHandler.FetchChildData(Master);PlanningFinder、OperationsFinder和MaintenanceFinder都是DetailFinder的子类。我刚刚被要求增加对另一业务线的支持,如果停止这种趋势,我不愿意继续这样做。我更喜欢有一个如下所示的解析方法:DetailFinderDetailHandler=DetailFinder.Parse(ReportType);但是,我的DetailFinder知道如何让DetailFinder知道哪个子类处理每个字符串,甚至知道哪个子类存在,而不仅仅是将if块移动到Parse方法。有没有办法让子类在抽象DetailFinder中注册自己?您可能想使用类型映射来创建方法:publicclassDetailFinder{privatestaticDictionary>Creators;staticDetailFinder(){Creators=newDictionary>();Creators.Add("规划",CreatePlanningFinder);Creators.Add("操作",CreateOperationsFinder);...}publicstaticDetailFinderCreate(stringtype){returnCreators[type].Invoke();}privatestaticDetailFinderCreatePlanningFinder(){returnnewPlanningFinder();}privatestaticDetailFinderCreateOperationsFinder(){returnnewOperationsFinder();}...}用作:DetailFinderdetailHandler=DetailFinder.Create(ReportType);我不确定这比if语句好多少,但它确实使它易于阅读和扩展。只需在Creators地图中添加创建方法和条目即可。另一种方法是存储报告类型和查找器类型的映射,然后在类型上使用Activator.CreateInstance,如果您总是只调用构造函数。如果对象的创建比较复杂,上面的工厂方法细节可能更合适。publicclassDetailFinder{privatestaticDictionaryCreators;静态DetailFinder(){Creators=newDictionary();Creators.Add("规划",typeof(PlanningFinder));...}publicstaticDetailFinderCreate(stringtype){Typet=Creators[type];将Activator.CreateInstance(t)作为DetailFinder返回;您可以使用IoC容器,其中许多允许您使用不同的名称或策略注册多个服务。例如,对于一个假设的IoC容器,您可以这样做:IoC.Register("Planning");IoC.Register("操作");...然后:DetailHandlerhandler=IoC.Resolve("Planning");关于这个主题的一些变化。可以看看下面的IoC实现:只要是大的if块或者switch语句或者只出现在一个地方,对可维护性来说都不错,所以不用担心这个原因。但是,当谈到可扩展性时,情况就不同了。如果您真的希望新的DetailFinder能够自行注册,您可能需要查看ManagedExtensibilityFramework,它实际上允许您将新程序集拖放到您的Add-ins文件夹或类似文件夹中,然后核心应用程序将获取新的DetailFinders自动。但是,我不确定这是否是您真正需要的可伸缩性。为了避免不断增长的if..else块,您可以将其切换为循环,以便各个查找器将它们处理的类型注册到工厂类。初始化的工厂类需要发现所有可能的查找器并将它们存储在哈希映射(字典)中。正如MarkSeemann所建议的,这可以通过反射和/或使用托管可扩展性框架来完成。但是-小心不要使它过于复杂。喜欢做最简单的事情,现在可能会起作用,因此可以根据需要重新设计它们。如果您只需要一个查找器类型,请不要构建复杂的自配置框架;)您可以使用反射。DetailFinder的Parse方法有一个示例代码(请记住向该代码添加错误检查):publicDetailFinderParse(ReportTypereportType){将Activator.CreateInstance(Type.GetType(detailFinderClassName))作为DetailFinder返回;GetDetailFinderClassNameByReportType方法可以从数据库、配置文件等中获取类名。我认为有关“插件”模式的信息对您的情况很有用:EA的EA:Plugin就像马克说的那样,一个大的if/switch块不是不错,因为它们都在一个地方(所有计算机科学基本上都是关于在某种空间中获得相似性)。也就是说,我可能只使用多态性(从而使类型系统为我工作)。让每个报表都实现一个FindDetails方法(我让它们继承自Report抽象类),因为无论如何您最终都会得到几种详细信息查找器。这也模拟了功能语言的模式匹配和代数数据类型。以上就是C#学习教程:C#:抽象策略基类,作为Strategy对象的抽象工厂,分享所有内容。如果对大家有用,需要了解更多C#学习教程,希望大家多多关注——本文来自网络收藏,不代表立场,如涉及侵权,请点击右转联系管理员删除。如需转载请注明出处: