背景: 想象一下形状的艺术品,其中有多层嵌套形状。属性的变化,例如任何这些形状内的形状的面积和长度都会导致所有相关的属性和形状发生变化。
我的设计模式是这样的:
我有一个对象图(称为讨论)“NestedShapes”,它有许多彼此相关的属性,例如“Area”和“Length”。但是图表被设计为愚蠢的,即给定任一值,它不知道如何计算另一个,也不会这样做。
相反,图形可以附加到GraphManager,它在其构造函数中采用顶级根节点IRootShape。
NestedShapes实现IRootShape,它也实现了INotifyPropertyChanged。 GraphManager订阅这些属性更改,并运行逻辑来计算相关字段,并通过IRootShape将图表设置为正确的状态。
问题: 与IRootShape一起,我有IShape,ISquare,ICircle等,这些都是真正的C#接口。但问题是这些属性中的一些我只希望它们具有GraphManager专用的setter。我知道实现形状仍然可以暴露公共setter,但我不希望必然在UI端公开这些以便能够从GraphManager设置属性。我该怎么办?内部基类设置的方法是什么?
答案 0 :(得分:2)
让GraphManager与Base类进行交互。
其他所有内容仅与界面交互。
不要在界面中公开属性。
public class Circle : ICircle{
public double Radius{
get;set;
}
/* blah blah ... */
}
public interface ICircle {
/* No properties */
/* blah blah ...*/
}
答案 1 :(得分:1)
通过接口执行此操作的技巧是使用两个单独的接口;一个公共,一个是内部的。是的,它需要更多的代码,因为你必须明确地实现内部接口,手动将其属性契约委托给实际的属性,但我只是将它隐藏在名为'ClassName.Internal.cs'的文件中的部分类中/ p>
通过这种方式,您可以清楚,干净地使用所需的确切权限公开接口,而无需使用基类,因此此技术也可用于扩展现有的对象图。
这是一个带有公共getter和内部setter的TestItem示例,所有这些都可以通过接口访问。
这是带有公共接口的主类文件,存储在TestItem.cs
中public interface ITestItem
{
ModelItem Owner { get; }
ModelScope Scope { get; }
}
public partial class TestItem : ITestItem
{
// These implicitly handle ITestItem since the getters are public
public ModelItem Owner { get; internal set; }
public ModelScope Scope { get; internal set; }
}
这是存储在TestItem.Internal.cs中的内部实现,通过部分类实现。
internal interface IWritableTestItem
{
ModelItem Owner { get; set; }
ModelScope Scope { get; set; }
}
public partial class TestItem : IWritableTestItem
{
ModelItem IWritableTestItem.Owner
{
get => Owner;
set => Owner = value;
}
ModelScope IWritableTestItem.Scope
{
get => Scope;
set => Scope = value;
}
}
希望这有帮助!