我正在开发一个用于使用模式的库,其中域逻辑如下:
- 有一个计划;
- 架构可以包含表格或图片,但不能同时包含两种内容。
如果将使用我的库的开发人员尝试访问表 ( Scheme.Table.Rows) 并且架构没有表,那么NullReferenceException我希望抛出一个更容易理解的错误,而不是 。并决定实施该模式Null Object。
界面
现在这是通过界面完成的,这就是它在项目中的外观:
public class Scheme
{
public ITable Table { get; }
public IPicture Picture { get; }
/// <summary>
/// Creates a new <see cref="Scheme"/> instance with table content.
/// </summary>
public Scheme(ITable table)
{
Table = table;
Picture = new NoPicture();
}
/// <summary>
/// Creates a new <see cref="Scheme"/> instance with picture content.
/// </summary>
public Scheme(IPicture picture)
{
Table = new NoTable();
Picture = picture;
}
}
public interface ITable
{
IEnumerable<Row> Rows { get; }
}
public class Table : ITable
{
public IEnumerable<Row> Rows { get; }
}
public class NoTable : ITable
{
public IEnumerable<Row> Rows => throw new Exception("Scheme does not contain a table.");
}
public interface IPicture
{
Image Image { get; }
}
public class Picture : IPicture
{
public Image Image { get; }
}
public class NoPicture : IPicture
{
public Image Image => throw new Exception("Scheme does not contain a picture.");
}
抽象类
下面是它在抽象类上的样子:
public class Scheme
{
public AbstractTable Table { get; }
public AbstractPicture Picture { get; }
/// <summary>
/// Creates a new <see cref="Scheme"/> instance with table content.
/// </summary>
public Scheme(AbstractTable table)
{
Table = table;
Picture = new NoPicture();
}
/// <summary>
/// Creates a new <see cref="Scheme"/> instance with picture content.
/// </summary>
public Scheme(AbstractPicture picture)
{
Table = new NoTable();
Picture = picture;
}
}
public abstract class AbstractTable
{
public abstract IEnumerable<Row> Rows { get; }
}
public class Table : AbstractTable
{
public override IEnumerable<Row> Rows { get; }
}
public class NoTable : AbstractTable
{
public override IEnumerable<Row> Rows => throw new Exception("Scheme does not contain a table.");
}
public abstract class AbstractPicture
{
public abstract Image Image { get; }
}
public class Picture : AbstractPicture
{
public override Image Image { get; }
}
public class NoPicture : AbstractPicture
{
public override Image Image => throw new Exception("Scheme does not contain a picture.");
}
问题
这是可以使用接口或抽象类实现相同事物的另一种情况。但从逻辑和设计的角度来看,哪个更正确?
我通常使用抽象类将公共代码放在单独的位置,最重要的是,实体之间的关系是IS类型,但我发现很难说它是NoTabel什么AbstractTable。
我认为接口会更正确,这就是原因。
接口最初被认为是两个功能对象之间的中间对象。
发明抽象类是为了通过删除通用属性和方法来减少代码。
在您的情况下,如果您打算在其他项目中使用它,您可以更轻松地浏览界面。而且会更容易参考,接口上的注释也会更容易阅读。
为了解决这个问题
你不需要使用模式
Null Object。在属性中抛出异常就足够了:Table如果您需要对and的依赖关系的抽象,请Picture添加接口:是否有多种具有通用代码的接口实现?添加一个抽象类: