1 回答
TA贡献1816条经验 获得超6个赞
我还没有想出一个完美的方法来做我想做的事,但我会将我的答案分成两个选项,每个选项都有优缺点。如果您正在为自己的类似问题寻求解决方案,您可能希望选择选项 1。
选项 1:良好的接口
这里的主要问题(正如@Servy 指出的)是接口应该真正包含执行其预期目的所需的所有操作。上面例子的样子可能是这样的:
public interface IRenderer
{
void Draw(/* Params needed to draw */);
}
public interface IOption
{
//Some Shared attributes for all Options
IRenderer Renderer { get; }
}
然后,呈现库可以提供(可能是抽象的)接口的实现,这些实现是从 IOption 派生的,客户端可以使用这些实现来呈现选项,或者继承并覆盖或简单地实例化和使用。
渲染器代码:
public abstract class RendererOptionCheckbox : IOptionCheckbox
{
public IRenderer Renderer => new CheckboxRender();
public abstract void OnValueChanged(bool newValue);
}
客户代码:
public class MyCheckBox : RendererOptionCheckbox
{
void OnValueChanged(bool newValue)
{
// Do something specific here when user checks/unchecks option
}
}
优点:
无需向上转换以渲染 IOption 列表,因为每个选项都知道如何渲染自身
暴露基本 IOption 接口没有问题,因为如果客户端尝试使用它,则必须定义渲染器
客户端可以使用自定义呈现逻辑注入他们自己的自定义 IOption
缺点:
客户端可以使用自定义渲染逻辑注入他们自己的自定义 IOption(这是一把双刃剑,你可能不想要这个)
客户端需要实例化直接从渲染器继承的对象,使得实际渲染器和客户端之间的耦合比我想要的更紧密。
选项 2:记录您的问题
只需按照原始问题中的描述编写代码,使用向上转换来执行渲染,如果直接实现 IOption 则抛出详细的异常,并提供有效使用与无效使用类的良好文档(如@DanWilson 建议的那样)。
优点:
从客户的角度清洁界面(看不到渲染逻辑)
客户端可以使用接口而不必担心要实例化或继承哪些相关的渲染器特定类
无需更改客户端代码即可轻松交换渲染器
缺点:
向上转换以呈现 IOptions 列表(糟糕!)
IOption 已公开但不能直接使用(令人困惑)
- 1 回答
- 0 关注
- 148 浏览
添加回答
举报