gpt4 book ai didi

c# - 对象 A 引用对象 B,对象 B 将对象 A 作为公共(public)属性(property) - 糟糕的设计?

转载 作者:行者123 更新时间:2023-11-30 22:40:03 25 4
gpt4 key购买 nike

我有一个上下文对象,它有几个有用的属性和方法。其他对象在其构造函数中接受此上下文对象。但是,上下文对象可以将这些其他对象作为公共(public)属性。见下文:

public class Foo {
private IContext Context { get; private set; }

public Foo( IContext context ) {
Context = context;
}
}

public class SomeContext : IContext {
public Foo SomeProperty { get; set; }
/*
Other useful properties and methods as defined in IContext
*/

public SomeContext () {
SomeProperty = new Foo( this );
}
}

现在我可以在 Foo 的方法中做一些有用的事情了:

public void FooIt() {
IUseful bar = this.Context.GetUsefulInterface();
bar.DoUsefulThing();
}

但是,它可能会导致一些非常奇怪的事情。考虑 Foo 上的这些方法:

public void DoSomething() {
/* useful stuff */
}

public void DoSomethingElse() {
this.Context.SomeProperty.DoSomething(); // could just call this.DoSomething();
this.Context.SomeProperty.DoSomethingElse(); // stack overflow!
}

这是否被认为是糟糕的设计/代码味道?上下文对象的原因有些牵扯,我想将问题更多地指向循环引用。如果认为不好,有哪些方法可以打破这种循环关系?

最佳答案

如果没有领域知识,在尝试设计循环依赖时很难知道从哪里开始,所以我只是概括一下。

当您不表达层次关系时,循环引用是不好的,在这种关系中返回父级是必需的或有用的。这是因为它促进了循环中类型之间的强耦合,很难正确地构造/删除,并且在遍历时容易出现错误。

但是,当您具有层次关系时,并且需要/有用地遍历层次结构,那么循环引用就非常有意义了。

您可能想要避免的一件事是尝试一次对您的属性进行过深的调用。这会增加您的耦合度,并且很容易导致错误,例如您发现的堆栈溢出异常。

// Reaches too far.  Makes this depend on the interface of SomeProperty
this.Context.SomeProperty.DoSomething();

// ...

// Not reaching too far. Only depends on Context.
// This might forward to SomeProperty.DoSomething()
this.Context.DoSomething();

根据您修复它的方式,这也可能有助于您解决堆栈溢出问题。

参见:http://en.wikipedia.org/wiki/Law_of_Demeter

关于c# - 对象 A 引用对象 B,对象 B 将对象 A 作为公共(public)属性(property) - 糟糕的设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5395961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com