Kev*_* P. 7 .net c# class-design reference class
我正在研究C#.NET中的业务问题.我有两个名为C和W的类,它们将在不同的时间独立实例化.
类C的对象需要包含对类W的0 ... n个对象的引用,即C对象最多可包含n个W对象.
每个W对象需要包含对C类的1个对象的引用,即W对象包含在一个C对象中.
通常首先实例化C类的对象.稍后,将发现并实例化其W内容.在此之后,我需要将C和W对象相互交叉引用.
这有什么好的设计模式?我实际上有一些案例,其中涉及三个或四个类,但我们可以讨论两个类来保持简单.
我在考虑一些简单的事情:
class C
{
public List<W> contentsW;
}
class W
{
public C containerC;
}
Run Code Online (Sandbox Code Playgroud)
这将暂时起作用,但我可以预见必须编写相当数量的代码来跟踪所有引用及其有效性.我想在后面实现代码,只对容器进行浅刷新,并对所有引用类进行深度刷新.还有其他方法,它们有什么优势?
编辑11/3:感谢所有人的好答案和良好的讨论.我最终选择了jop的答案,因为它最接近我想做的事,但其他答案也有帮助.再次感谢!
如果您有Martin Fowler的重构书,请按照"将单向关联更改为双向"重构.
如果你没有它,这里是你的类在重构后的样子:
class C
{
// Don't to expose this publicly so that
// no one can get behind your back and change
// anything
private List<W> contentsW;
public void Add(W theW)
{
theW.Container = this;
}
public void Remove(W theW)
{
theW.Container = null;
}
#region Only to be used by W
internal void RemoveW(W theW)
{
// do nothing if C does not contain W
if (!contentsW.Contains(theW))
return; // or throw an exception if you consider this illegal
contentsW.Remove(theW);
}
internal void AddW(W theW)
{
if (!contentW.Contains(theW))
contentsW.Add(theW);
}
#endregion
}
class W
{
private C containerC;
public Container Container
{
get { return containerC; }
set
{
if (containerC != null)
containerC.RemoveW(this);
containerC = value;
if (containerC != null)
containerC.AddW(this);
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意我已经List<W>私有化了.通过枚举器公开Ws列表,而不是直接公开列表.
例如public List GetWs(){return this.ContentW.ToList(); }
上面的代码正确处理所有权的转移.假设您有两个C - C1和C2实例 - 以及W - W1和W2的实例.
W1.Container = C1;
W2.Container = C2;
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,C1包含W1,C2包含W2.如果将W2重新分配给C1
W2.Container = C1;
Run Code Online (Sandbox Code Playgroud)
然后C2将有零项,C1将有两个项目 - W1和W2.你可以有一个漂浮的W.
W2.Container = null;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,W2将从C1的列表中删除,它将没有容器.您还可以使用C中的Add和Remove方法来操作W的容器 - 因此C1.Add(W2)将自动从其原始容器中删除W2并将其添加到新容器中.