当这些类型的消费者紧密耦合时,避免使用许多类型参数的通用类

发布于 2025-01-28 11:11:57 字数 1562 浏览 3 评论 0原文

我正在尝试提出一种方法来做到这一点,但我可以拥有类型的安全性,但我班上几个不同的组件也松散了耦合。

我正在进行校准分析,通常有3个部分。分析,验证和生成报告。

因此,我想做的是拥有一个具有方法文档的基本校准类。然后,我可以让子类从校准中继承并注入正确的依赖项,以便运行上述步骤。我最初的想法是,如下所示

public class Calibration 
{
  readonly IAnalyzer _analyzer;
  readonly IVerifier _verify;
  readonly IReportGenerator _reportGen;

  public Calibration(IAnalyzer analyzer, 
                     IVerifier verifier, 
                     IReportGenerator generator)
 {
     _analyzer = analyzer;
     _verifier = verifier;
     _reportGen = generator;
 }

  public void DoCalibration()
  {
     var data; //would get most likely from a data reader
     var analyzeResult = _analyzer.Analyze(d);
     var verifyResult = _verifer.Verify(analyzeResult);
     var report = _reportGen.Generate(verifyResult);     
  }
}

,我的分析仪,验证仪和报告的生成非常紧密,因为分析仪的类型与验证结果的验证方法耦合,依此类推。因此,如果我希望这是通用的,那么我必须做类似的事情

public class Calibration<TAnalyzeResult, TVerifyResult>
{
   IAnalyzer<TAnalyzeResult> _analyzer;
   IVerifier<TAnalyzeResult, TVerifyResult> _verifier;
   IReportGenerator<TVerifyResult> _reportGen
}

public interface IAnalyzer<TAnalyzeResult>{
    TAnalyzeResult Analyze(Data d);
}

public interface IVerifier<TAnalyzeResult, TVerifyResult>{
    TVerifyResult Verify(TAnalyzeResult analyzeResult);
}

//etc

,但是,如果我想添加类似于特定报告类型的报告中的某种处理,我必须继续添加类型的参数参加我的校准课。对我来说,这是一种代码气味,但我不知道如何获得类型的安全性,还可以强制执行每个校准调用分析,验证,生成报告的事实。

因此,总而言之,我想使用以下事实:我可以拥有多种校准儿童类型,这些类型都遵循类似的处理流,我可以将其推入基础,但是我不知道如何在保持类型安全性的同时将它们解散。

I am trying to come up with a way to do this where I can have type safety but also loose coupling of a couple of different components in my class.

I am running a calibration analysis which in general has 3 parts. Analyze, Verify, and Generate Report.

So what I would like to do is have a base calibration class with a method DoCalibration. I can then have child classes inherit from Calibration and inject the correct dependencies in order to run the above steps. My initial thought was to have something as follows

public class Calibration 
{
  readonly IAnalyzer _analyzer;
  readonly IVerifier _verify;
  readonly IReportGenerator _reportGen;

  public Calibration(IAnalyzer analyzer, 
                     IVerifier verifier, 
                     IReportGenerator generator)
 {
     _analyzer = analyzer;
     _verifier = verifier;
     _reportGen = generator;
 }

  public void DoCalibration()
  {
     var data; //would get most likely from a data reader
     var analyzeResult = _analyzer.Analyze(d);
     var verifyResult = _verifer.Verify(analyzeResult);
     var report = _reportGen.Generate(verifyResult);     
  }
}

However, my analyzer, verifier, and report generation are very tightly coupled, as the type of analyzeResult is coupled to the verify method of the verify result, and so on. So if I want this to be generic, I have to do something like

public class Calibration<TAnalyzeResult, TVerifyResult>
{
   IAnalyzer<TAnalyzeResult> _analyzer;
   IVerifier<TAnalyzeResult, TVerifyResult> _verifier;
   IReportGenerator<TVerifyResult> _reportGen
}

public interface IAnalyzer<TAnalyzeResult>{
    TAnalyzeResult Analyze(Data d);
}

public interface IVerifier<TAnalyzeResult, TVerifyResult>{
    TVerifyResult Verify(TAnalyzeResult analyzeResult);
}

//etc

However, if I want to add something like, say, some sort of processing to the report that is dependent on a specific report type, I have to keep adding type parameters to my calibration class. This to me is a code smell, but I can't figure out how to get type safety but also enforce the fact that every calibration calls Analyze, verify, generate report.

So to summarize, I would like to use the fact that I can have multiple calibration child types which all follow a similar processing flow which I can push into the base class, but I can't figure out how to decouple them while keeping type safety.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空城仅有旧梦在 2025-02-04 11:11:57

让我们首先为您的校准创建一些基类。 现在,这包括一个接口,

// Calibration Base class
public class Calibration<TAnalyzeResult, TVerifyResult>
    : ICalibration<TAnalyzeResult, TVerifyResult>
{
    IAnalyzer<TAnalyzeResult> _analyzer;
    IVerifier<TAnalyzeResult, TVerifyResult> _verifier;
    IReportGenerator<TVerifyResult> _reportGen

    public virtual void DoCalibration()
    {
        // Do your base calibration code here
    }
}

public interface ICalibration<TAnalyzeResult, TVerifyResult>
{
    void DoCalibration();
}

我们要做的是让一个孩子从基本校准类中遗传,类似于我们也为此课程做一个接口。
这将允许的是相当容易地进行依赖注入。

// An interface for your chilc calibration
public interface IIndepthCalibration
    : ICalibration<MyChosenAnalyzeResylt, MyChosenVerifyResylt> { }

// Class for the cild calibraiton
public class IndepthCalibration
    : Calibration<MyChosenAnalyzeResylt, MyChosenVerifyResylt>, IIndepthCalibration
{
    public IndepthCalibration(
        IAnalyzer analyzer, // Required Injection
        IVerifier verifier, // Required Injection
        IReportGenerator generator, // Required Injection
        IMyCustomInjection)         // Injection used in this class alone
        : base(analyzer, verifier, generator)
    {
        // Constructor for the new calibration type
    }

    // OPTIONAL
    // If you want to add custom code to your DoCalibration Funciton
    public override void DoCalibration()
    {
        // Maybe you want to run the Base then do some additional
        base.DoCalibration();

        // Now you do your own
        // HERE
    }
}

最后,注册您的新类依赖项,

builder.services.AddTransient<IIndepthCalibration, IndepthCalibration>();

如果需要,这将允许使用自定义类:

public class MyApp
{

    void MyApp(IIndepthCalibration indepthCalc)
    {
        indepthCalc.DoCalibration();
    }
}

希望这将帮助您保持TypesAfety而不添加太多东西。

Lets first create some base classes for your calibration. This includes an interface

// Calibration Base class
public class Calibration<TAnalyzeResult, TVerifyResult>
    : ICalibration<TAnalyzeResult, TVerifyResult>
{
    IAnalyzer<TAnalyzeResult> _analyzer;
    IVerifier<TAnalyzeResult, TVerifyResult> _verifier;
    IReportGenerator<TVerifyResult> _reportGen

    public virtual void DoCalibration()
    {
        // Do your base calibration code here
    }
}

public interface ICalibration<TAnalyzeResult, TVerifyResult>
{
    void DoCalibration();
}

Now what we do is we get a child that inherrits from the base calibration class, similar we do a interface for this class as well.
This will allow is to do dependency injection fairly easily.

// An interface for your chilc calibration
public interface IIndepthCalibration
    : ICalibration<MyChosenAnalyzeResylt, MyChosenVerifyResylt> { }

// Class for the cild calibraiton
public class IndepthCalibration
    : Calibration<MyChosenAnalyzeResylt, MyChosenVerifyResylt>, IIndepthCalibration
{
    public IndepthCalibration(
        IAnalyzer analyzer, // Required Injection
        IVerifier verifier, // Required Injection
        IReportGenerator generator, // Required Injection
        IMyCustomInjection)         // Injection used in this class alone
        : base(analyzer, verifier, generator)
    {
        // Constructor for the new calibration type
    }

    // OPTIONAL
    // If you want to add custom code to your DoCalibration Funciton
    public override void DoCalibration()
    {
        // Maybe you want to run the Base then do some additional
        base.DoCalibration();

        // Now you do your own
        // HERE
    }
}

Finally register your new class dependencies

builder.services.AddTransient<IIndepthCalibration, IndepthCalibration>();

this will allow use to inject the custom class if needed:

public class MyApp
{

    void MyApp(IIndepthCalibration indepthCalc)
    {
        indepthCalc.DoCalibration();
    }
}

Hopewfully this will help you to keep the typesafety without adding too many things.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文