我有一个抽象类“A”,它具有枚举类型“OutputType”的属性,还有一个抽象方法calculation(),它需要执行certin计算,并根据OutputType值以double[]**形式输出结果。
我也有一个类定义为D1,D2,D3...D20,从A派生,其中每个Di类实现A的计算()方法不同。
问题是并非所有的OutputType值(calculation()输出类型)都在每个Di中都受支持
例如:
如果OutputType枚举值为“缩放”、“非缩放”和“恒定长度”,
一个认证Di可以支持“缩放”和“非缩放”,但不支持“恒定长度”,另一个Di可以支持所有操作类型,
我的问题是:
实现这种行为的正确设计模式是什么
请避免明显的“如果输出类型属性接收到不支持的操作的值,则抛出”回答。
编辑:
扩展问题:
有没有一种方法可以用intellisense通知用户所有支持的操作,这样用户就不必采取试错法?(除了适当的文件)
请注意,我已经编辑了我的答案,完全放弃了我以前使用代码契约的先决条件的方法。
我一直在想一个应该更强大的解决方案。
一个抽象类为每个可能的操作类型定义了一个受保护的虚拟方法,一个不可覆盖的公共计算方法可以调用覆盖的受保护的虚拟方法呢?
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。“以我的身材。格雷德尔。 有人知道吗? 我的错
由于我正在学习通过设计模式的概念,也希望实现支付模块在我的项目中使用适当的设计模式。为此,我创建了一些示例代码。 目前,我有两个具体的实现支付和。但具体实施将在项目上进一步补充。 支付服务 信用卡和付费朋友服务 客户端代码实现 此更新是否与策略模式内联?