How to deal with temporal coupling?

半世苍凉 提交于 2019-12-05 11:18:44

If you follow Anemic Domain Model, you can break your class and make it 2 smaller classes. You become aware of bad design because your current class violates SRP, in short it has 2 responsibility: 1 for handle the input process, 1 for process the input result.

Break it down so that ClassA will handle the input and returning result, then ClassB will take the result from ClassA as parameter, then process it. ex:

public class ClassA
{
    public string MethodA()
    {
        // read the input
        return "Something"; // or return the input
    }
}

public class ClassB
{
    private int count;
    public void MethodB(string str)
    {
        count = str.Length;
    }
}

If you find the use of both class is bothersome, use another aggregate service for that. ex:

public class ClassC
{
    public ClassA ClassA = new ClassA();
    public ClassB ClassB = new ClassB();
    public void Execute(){
        string result = ClassA.MethodA();
        ClassB.MethodB(result);
    }
}

I guess you need to have a sort of complex initialization, in which some parameters have to be specified before actually initialize the object, and you want a better control on what the class user is doing to avoid invalid states. A good know pattern to solve such situation is the so called "Builder Pattern", very frequently used in OOP. I don't want to point a particular article, you will find yourself a lot of examples by just using the keyword "builder pattern". Just to be complete, the overall idea is to make a fluent sequence of method specifying values of internal fields, and delegate a final method "Build" to create an working object instance, and validate the parameters passed.

Fluent API's solve this kind of thing on public interfaces by not exposing dependent methods in the "builder" object until appropriate:

SomeClass someInstance = SomeClassBuilder(x=> { 
     x.MethodA().MethodB("somevalue");
});

This requires alot more plumbling because you need the builder object, as well as builder components such as an object that is returned from MethodA which exposes MethodB. This way the only way to call MethodB is to first call MethodA.

I'm not encouraging you to take this approach. It's probably overkill for many scenarios, but is important to be aware of this option in case you encounter a scenario where it is appropriate.

adricadar

You can just remove the parameter from MethodB and use the field, in this way you don't lose cohesion

private class SomeClass
{
    private string field;
    private int count;

    public SomeClass()
    {
        MethodA();
        MethodB();
    }

    private void MethodA()
    {
        field = "Something";
    }

    private void MethodB()
    {
        count = field.Length;
    }
}

Notes:

1) The way you describe the problem seems like Template Method design pattern, you should have a look here.

2) Static methods don't belong to that class

I don't know what is your exact goal, but why not put the parameter in the constructor of the class:

private class SomeClass
{
    private string _field;
    private int _count;

    public SomeClass(string field)
    {
        _field = field;
        _count = field.Length;
    }

}

Now you will have something like this

SomeClass sc = new SomeClass("Something");//or whatever you want for field.
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!