【问题标题】:Constructor arguments for Factory in C#, am I doing it right?C# 中 Factory 的构造函数参数,我做得对吗?
【发布时间】:2016-02-23 12:18:01
【问题描述】:

我在下面解释了我的问题,我的问题是: 1.我是否正确使用工厂模式来解决这个问题 2. 我做得对吗?

我有一个你可以称之为事件跟踪系统的系统,它由工人/经理在建筑工地使用,它是在 ASP.NET MVC 中开发的,该应用程序存储在不同位置发生的不同类型的事件。现在我必须为用户提供一种根据位置、事件类型等生成报告的方法。

这就是我在代码中的做法(为简洁起见,在某些部分包含 cmets 而不是代码) -

//Controller methods
public ActionResult ReportByLocation(){
    var incidents = GetDataFromRepo();
    var reportFactory = new IncidentReportFactory(incidents, "ByLocation");
    var pdfView = new ReportsGenerator(reportFactory).GetPdfView();
    return pdfView;
}

public ActionResult ReportByType(){
    var incidents = GetDataFromRepo();
    var reportFactory = new IncidentReportFactory(incidents, "ByType");
    var pdfView = new ReportsGenerator(reportFactory).GetPdfView();
    return pdfView;
}

//Concrete factory class
public class IncidentReportFactory : ReportFactory{
    public IncidentFactory(List<Incident> incidents, string reportType){
        //Initialize properties
    }

    public ConcreteReport CreateConcreteReport(){
        switch(ReportType){
            case "ByLocation": return new IncidentLocationReport(incidents);
                               break;
            case "ByType": return new IncidentTypeReport(incidents);
                           break;
        }
    }
}

//ConcreteReport class
public class IncidentLocationReport : ConcreteReport{
    public IncidentLocationReport(List<Incident> incidents){
         //Constructor which sorts, splits, etc. based on location 
         //and returns
    }
}

//Report generator class
public ReportsGenerator{
     public ReportsGenerator(ReportFactory factory){
           Factory = factory;
     }

     public PDFView GetPdfView(){
          var report = factory.CreateConcreteReport();
          var pdfView = ConstructPdfWithAllFormatting(report);
          return pdfView;
     }
}

另请注意,我是从抽象工厂和具体类继承的 我的代码有意义吗?还是我做错了?请指出我正确的方向。谢谢!

【问题讨论】:

    标签: c# asp.net-mvc design-patterns factory


    【解决方案1】:

    基本上你是对的。

    你有类 IncidentReportFactory 和方法 CreateConcreteReport 创建 ConcreteReport 对象依赖于 reportType

    从抽象类继承是我的观点,我认为不是 nessesery。您的 ReportFactory 抽象类没有方法,因此不需要使用它。当不能共享方法时,它是低抽象的。有接口这样做很好。

    public interface IIncidentReportFactory
    {
     public IConcreteReport CreateConcreteReport();
    }
    

    以及实现:

    public class IncidentReportFactory : IIncidentReportFactory
    {
        public IncidentFactory(List<Incident> incidents, string reportType)
        {
            //Initialize properties
        }
    
        public ConcreteReport CreateConcreteReport()
        {
            switch(this.ReportType)
            {
                case "ByLocation": return new IncidentLocationReport(incidents);
                                   break;
                case "ByType": return new IncidentTypeReport(incidents);
                               break;
            }
    
          return null //no match
        }
    

    您还必须更改一些名称:

    var reportFactory = new IncidentReportFactory(incidents, "ByLocation");
    

    reportFactory 是一个很容易被误解的名字。不是reportFactoryConcreteReport 对象。

    当您将抽象类更改为接口时,ReportsGenerator 类应该像这样

    //Report generator class
    public ReportsGenerator{
         public ReportsGenerator(IConcreteReport concreteReport){
               this.concreteReport= concreteReport;
         }
    
         public PDFView GetPdfView(){
    
              var pdfView = ConstructPdfWithAllFormatting(this.concreteReport);
              return pdfView;
         }
    }
    

    使用Dependency Injection Container也是一个好习惯

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 2013-03-05
      • 2012-06-30
      • 2015-01-31
      • 2013-02-17
      • 1970-01-01
      相关资源
      最近更新 更多