当前位置: 首页 > 知识库问答 >
问题:

支持的操作设计模式

姜奇
2023-03-14

我有一个抽象类“A”,它具有枚举类型“OutputType”的属性,还有一个抽象方法calculation(),它需要执行certin计算,并根据OutputType值以double[]**形式输出结果。

我也有一个类定义为D1,D2,D3...D20,从A派生,其中每个Di类实现A的计算()方法不同。

问题是并非所有的OutputType值(calculation()输出类型)都在每个Di中都受支持

例如:

如果OutputType枚举值为“缩放”、“非缩放”和“恒定长度”,

一个认证Di可以支持“缩放”和“非缩放”,但不支持“恒定长度”,另一个Di可以支持所有操作类型,

我的问题是:

实现这种行为的正确设计模式是什么

请避免明显的“如果输出类型属性接收到不支持的操作的值,则抛出”回答。



编辑:

扩展问题:

有没有一种方法可以用intellisense通知用户所有支持的操作,这样用户就不必采取试错法?(除了适当的文件)

共有1个答案

越飞翮
2023-03-14

请注意,我已经编辑了我的答案,完全放弃了我以前使用代码契约的先决条件的方法。

我一直在想一个应该更强大的解决方案。

一个抽象类为每个可能的操作类型定义了一个受保护的虚拟方法,一个不可覆盖的公共计算方法可以调用覆盖的受保护的虚拟方法呢?

public abstract class Calculation
{
    public Calculation()
    {
        // I store all overridable methods in a dictionary where keys
        // are the method names
        OverridableMethods = new Dictionary<string, Func<double[]>>()
        {
            { nameof(CalculateScaled), CalculateScaled },
            { nameof(CalculateNonScaled), CalculateNonScaled },
            { nameof(CalculateConstantLength), CalculateConstantLength }
        };


        // Then we get the first overriden method. If there're more
        // than one, it will pick the first occurence and others will be
        // discarded. It's up to the developer to override just one.
        MethodInfo overridenMethod = OverridableMethods.Keys
                .Select(methodName => GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic))
                .FirstOrDefault(method => method.DeclaringType != typeof(Calculation));

        Contract.Assert(overridenMethod != null, "No calculation operation implementation has been provided");

        // So some method was overriden and I store the method name
        OverridenMethodName = overridenMethod.Name;
    }

    private string OverridenMethodName { get; }
    private Dictionary<string, Func<double[]>> OverridableMethods { get; }

    protected virtual double[] CalculateScaled() 
    {
        throw new NotImplementedException();
    }

    protected virtual double[] CalculateNonScaled() 
    {
        throw new NotImplementedException();
    }

    protected virtual double[] CalculateConstantLength()
    {
        throw new NotImplementedException();
    }

    // Calculate just access the overridable method dictionary
    // to get the overriden method encapsulated by a Func<double[]>
    // and I immediately call it!
    public double[] Calculate() => OverridableMethods[OverridenMethodName]();
}

public class SomeCalculation : Calculation
{
    protected override double[] CalculateScaled()
    {
        return new double[] { 22 };
    }
}

所以它真的有效!

    Calculation calculation = new SomeCalculation();

    // Prints out 22!
    Console.WriteLine(calculation.Calculate()[0]);
 类似资料:
  • SDS 提供了以下一系列操作来处理表和记录 表操作 SDS 提供创建、修改、复制、禁用、启用和删除表的操作 创建表(createTable):以指定的表名和schema创建一张表 修改表(alterTable):可以增加或删除属性,修改表权限,修改读写配额、空间配额,修改二级索引类型等 复制表(cloneTable):从现有的表复制一张表名不同但内容一样的表 禁用表(disableTable):将

  • 有时候,同一个操作符会有多个别名,不同平台或实现有时也会让同一个操作符有不同的名字。有的是历史原因,或者撞上了语言的关键字。 当缺乏社区强烈共识前,RxSwift操作符通常包含多个别名。 操作符默认是无状态的。 创建 Observables asObservable create deferred empty error toObservable (array) interval never ju

  • 在绝大多数现代的Unix类操作系统(例如Linux、BSD等)上,只需要一个C++编译器就可以编译并运行Sphinx/Coreseek,而不需要对源码进行任何改动。 目前,Sphinx/Coreseek可以在以下系统上运行: Linux 2.4.x, 2.6.x (包括各种发行版,如Redhat、Centos、Debian、OpenSuse等) Windows 2000, 2003, XP, Vi

  • 我正在使用sql server进行数据库连接。并且我希望在运行多个结果集时保持结果集打开。我使用了,但在执行语句时出现以下错误, 由于我是使用sql server的新手,所以我对其中的一些概念还不是很了解。如果有人知道为什么会这样请回答我。

  • 我想用com。Android支持:设计:22.2.0在我的Android Studio(1.3)项目中,但当我添加'com'时。Android支持:设计:22.2.0'到依赖{}我有103个错误,我无法摆脱这个错误。 如果我尝试使用新版本的appcompat,也会发生同样的情况。现在我有了“com”。Android支持:appcompat-v7:19。“以我的身材。格雷德尔。 有人知道吗? 我的错

  • 由于我正在学习通过设计模式的概念,也希望实现支付模块在我的项目中使用适当的设计模式。为此,我创建了一些示例代码。 目前,我有两个具体的实现支付和。但具体实施将在项目上进一步补充。 支付服务 信用卡和付费朋友服务 客户端代码实现 此更新是否与策略模式内联?