简体   繁体   English

这是什么设计模式?

[英]What design pattern does this?

I did this once a long time ago and followed a design pattern when I did.很久以前我做过一次,当时我遵循了一个设计模式。 Now, I need to do it again, I don't really remember how I did it before, and I can't think of the pattern that helped me do it.现在,我需要再做一次,我真的不记得我以前是怎么做的,也想不出帮助我做这件事的模式。

I have a class with a whole slew of variables/properties.我有一个包含大量变量/属性的类。 Some are calculated based on the others, and there is all sorts of cross-calculating going on between these properties.有些是基于其他计算的,并且这些属性之间会进行各种交叉计算。

It's all fine when I first instantiate - all the values and the calculations work just fine.当我第一次实例化时一切都很好 - 所有的值和计算都很好。 My problem is, when one value changes, I want all of the calculated values derived from it to update themselves based on the new value automatically.我的问题是,当一个值发生变化时,我希望从中派生的所有计算值都能根据新值自动更新。 And I don't want to write each individual recalc manually if I don't have to - it just becomes a lot of overhead whenever this class gets updated or added to, trying to track down all of the places you need to propagate whatever change you're making.如果我不需要,我不想手动编写每个单独的重新计算 - 每当这个类被更新或添加时,它就会成为很多开销,试图追踪你需要传播任何更改的所有位置你在做。

I think you follow me.我想你跟着我。

Anyway, can anyone think of what pattern it is that makes this possible?无论如何,谁能想到是什么模式使这成为可能? I swear I used to know it.我发誓我曾经知道它。 Getting old I guess.估计变老了。

// Like this...
class foo
{
    decimal A = 1233;
    decimal B = 42;

    decimal C = A / B; // I want this to update whenever
                       // the value of either A or B changes.
    decimal D = 123;
    decimal E = 321;

    decimal F = D + E; // I don't want this one to change when
                       // A or B or even C for that matter changes,
                       // and I don't wan to have to cycle through
                       // all of the calculated values that don't
                       // need to change just for find the few that do.
}

Observer.观察员。 You need some kind of .Subscribe() method on your models that is used to register callbacks - in your specific cases those are just functions that take new value and recompute some others based on that one.您需要在模型上使用某种.Subscribe()方法来注册回调 - 在您的特定情况下,这些只是采用新值并基于该值重新计算其他一些值的函数。 As long as your programming environment has rxjs implementation(s), I strongly suggest to stick to that one.只要你的编程环境有rxjs实现,我强烈建议坚持使用那个。 Otherwise you'll suffer because of multithreading and memory leaks.否则你会因为多线程和内存泄漏而受苦。

I'd suggest to avoid over-engineering here.我建议避免在这里过度设计。 What you presented as an example has 6 members with simple dependencies between them that can be easily recalculated.您作为示例提供的内容有 6 个成员,它们之间具有简单的依赖关系,可以轻松地重新计算。 I do understand this can be just a simplified example, so let's aim for eg 10-20 members, and dependencies that don't require database lookups or disk access (as an example of heavier operations).我确实理解这可能只是一个简化的例子,所以让我们的目标是例如 10-20 个成员,以及不需要数据库查找或磁盘访问的依赖项(作为较重的操作的一个例子)。

You can put all dependencies into one method (let's call it Update ), which you call if any member is modified.您可以将所有依赖项放入一个方法中(我们称之为Update ),如果任何成员被修改,您将调用该方法。 To not worry about remembering to call Update() , you move all members into a separate "state" class:为了不用担心记得调用Update() ,您将所有成员移动到一个单独的“状态”类中:

class FooState
{
    private int _a;

    public int A
    {
        get { return _a; }
        set
        {
            _a = value;
            Update();
        }
    }

    private int _b;

    public int B
    {
        get { return _b; }
        set
        {
            _b = value;
            Update();
        }
    }

    public double C { get; private set; }

    // other members

    private void Update()
    {
        C = A * B + 3;
        // other updates
    }
}

class Foo
{
    private FooState _state;

    public Foo()
    {
        _state.A = 1;
        _state.B = 2;
        Debug.Write($"C = {_state.C}");
    }
}

What you get:你得到什么:

  • It's immediately clear what's going on.发生了什么事情马上就清楚了。 To anybody who will happen to modify this code.对于任何会碰巧修改此代码的人。
  • all dependencies between your members are in a single method, easy to read, easy to modify.成员之间的所有依赖项都在一个方法中,易于阅读,易于修改。 Your business logic is not polluted with this details.您的业​​务逻辑不会被这些细节污染。
  • You can't forget to recalculate your dependent members.你不能忘记重新计算你的依赖成员。
  • Yes you can do more recalculation than strictly required, as you recalculate all your dependent members even if an unrelated member was modified.是的,您可以进行比严格要求更多的重新计算,因为即使不相关的成员被修改,您也会重新计算所有依赖成员。 In the majority of similar cases I've seen in real file this wasn't a problem.在我在真实文件中看到的大多数类似案例中,这不是问题。
  • This approach doesn't work if you have cyclic dependencies (which is a different story).如果您有循环依赖(这是另一回事),则此方法不起作用。

Feel free to implement "observer" pattern and compare.随意实现“观察者”模式并进行比较。

I don't think this simple approach has the name.我不认为这种简单的方法有名字。 Don't confuse it with "State" pattern which is a bit different thing.不要将它与有点不同的“状态”模式混淆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM