对象A对对象B的引用,对象B具有对象A作为公共属性-设计不好? [英] Object A has a reference to Object B which has Object A as public property - bad design?

查看:79
本文介绍了对象A对对象B的引用,对象B具有对象A作为公共属性-设计不好?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a contextual object that has several useful properties and methods. Other objects accept this contextual object in their constructors. However, the contextual object can have these other objects as public properties. See below:

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上的方法中做一些有用的事情:

Now I can do something useful in a method on Foo:

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

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

However, it can lead to some really weird stuff. Consider these methods on Foo:

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

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

这被认为是不良的设计/代码异味吗?涉及上下文对象的原因有些涉及,我想将这个问题更多地归结为周期性引用.如果认为不好,有什么方法可以打破这种周期性关系?

Is this considered a bad design / code smell? The reasons for the contextual object are somewhat involved, and I'd like to frame the question more towards the cyclical reference. If considered bad, what are some approaches to breaking this cyclical relationship?

推荐答案

在没有领域知识的情况下,尝试设计循环依赖项时很难知道从何处开始,因此我将一概而论.

Without domain knowledge, it is hard to know where to start when trying to design out your cyclic dependency, so I'll just generalize.

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

Cyclic references are bad when you aren't expressing a hierarchical relationship, in which it is required or useful to get back to a parent. This is because it promotes strong coupling between the types in the cycle, it is difficult to construct/delete properly, and is prone to bugs when traversing.

但是,当您具有层次结构关系时,遍历该层次结构是必需的/有用的,那么具有循环引用是很有意义的.

However, when you have a hierarchical relationship, and it is required/useful to traverse back up the hierarchy, then it makes perfect sense to have cyclic references.

您可能要避免的一件事是尝试一次调用您的属性太深的内容.这样会增加耦合,并容易导致诸如已发现的堆栈溢出异常之类的错误.

One thing you may want to avoid is trying to call too deep into your properties at one time. This increases your coupling, and can easily lead to bugs like the stack overflow exception you have found.

// 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();

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

Depending on how you fix it, this might also help you break the stack overflow.

请参阅: http://en.wikipedia.org/wiki/Law_of_Demeter

这篇关于对象A对对象B的引用,对象B具有对象A作为公共属性-设计不好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆