以下类图是我正在处理的项目的简化版本。
A类负责序列化/反序列化以C为根的对象图。我正在使用Csharp的框架进行序列化,所以当我反序列化C类时,框架会创建一个以C为根的所有对象的新实例(图中显示的是*新类)。现在我想用Cnew替换A的C实例,但问题是B1和B2仍然指向旧的D1和D2。不必重新初始化B2和B2的依赖关系会很好。
我正在寻找一种方法让B1和B2能够通过A访问D1和D2,而不会让他们访问C或相互访问。为了简单起见,我们可以假设A的所有成员都必须是公共的(它实现了我正在使用的框架的接口,迫使很多成员公开)。
以下是我的一些潜在解决方案:
只需咬紧牙关并重新初始化B1和B2
为B1和B2提供对A的引用,而不是D1和D2,并忽略这一事实,即这使他们可以访问许多他们不需要访问的类。
不是给B类直接访问D类,而是在委托(函数指针)中为返回A的D1和D2实例的函数传递。
具有D1Container和D2Container之类的实现接口,它具有1个将实例返回到D1或D2的必需方法。然后将A转换为D1Container或D2Container并将其传递给B1和B2。
这种事情是否有设计模式,或者我的解决方案之一显然是最好的?
谢谢!
答案 0 :(得分:1)
您希望在设计中引入另一层次的间接性:本质上,您不是要存储对D1
和D2
的引用,而是希望存储能让您获得最新内容的内容{ {1}}和D1
。你的#3(委托)选项对我来说是最优雅的,因为你不需要引入新的类来实现延迟评估。您只需要D2
Func<D>
传递给A
- 没有新的类,接口或代理;一切都很好地封装了。
B
现在,如果class A {
private B myB;
private C myC;
public A() {
myC = new C();
myB = new B(() => myC.MyD);
}
}
class B {
private readonly Func<D> getD;
public B(Func<D> getD) {this.getD = getD;}
public D { get { return getD(); } }
}
class C {
public D MyD {get; private set;}
}
更改其A
,或C
更改其C
,D
将继续自动返回正确的B.D
。这是因为在D
下,B
拥有对A
的引用,但它不知道它的确如此。
答案 1 :(得分:0)
是一个问题,使其可以访问C
是最有前途的选择。我将通过B监听的A暴露事件来实现它。