简体   繁体   中英

OOP, enforcing method call order

Question:

This is a question about OOP practice. I've run into a situation while working with an API where there are a series of methods that need to be called in a specific order.

Case:

Controlling the operation of a smart sensor.

A simplified version of the interaction goes like this: first the API must be configured to interface with the sensor over TCP, the next command starts the scanning process, followed by receiving input for multiple items until the command to stop is given. At that time a similar series of disconnect commands must be given. If these are executed out of order an exception is thrown.

I see a conflict between the concepts of modularization and encapsulation here. Each of the steps is a discrete operation and thus should be encapsulated in separate methods, but they are also dependent on proper order of execution.

I'm thinking from the perspective of a later developer working on this code. It seems like someone would have to have a high level of understanding of this system before they could work on this code and that makes it feel fragile. I can add warning comments about this call order, but I'm hoping there's some principle or design pattern that might fit my situation.

Here's an example:

class RemoteTool
{
    public void Config();
    public void StartProcess();
    public void BeginListen();

    public void StopProcess();
    public void StopListening();
}

class Program
{
    static void Main(string[] args)
    {
        RemoteTool MyRemoteTool = new RemoteTool();

        MyRemoteTool.Config();
        MyRemoteTool.StartProcess();
        MyRemoteTool.BeginListen();

        // Do some stuff

        MyRemoteTool.StopListening();
        MyRemoteTool.StopProcess();
    }
}

The closest thing I can think of is to use boolean flags and check them in in each function to assure that the prerequisite functions have already been called, but I guess I'm hoping for a better way.

Here's a method I found while looking for an answer. It's pretty simple, it helps, but doesn't solve my issue.

Essentially the class is created exactly in the question, but the dependant functions are created as protected and a public member is created to keep them in order like so:

class RemoteTool
{
    public bool Running = false;
    public void Run()
    {
        Config();
        StartProcess();
        BeginListen();

        Running = true;
    }

    public void Stop() {
        StopListening();
        StopProcess();

        Running = false;
    }

    protected void Config();
    protected void StartProcess();
    protected void BeginListen();

    protected void StopProcess();
    protected void StopListening();
}

The trouble is that you still have to call Stop() and Run() in the right order, but they're easier to manage and the modularization is higher.

I think the problem is related to the fact that the RemoteTool class has a contract that requires some pre-condition. eg : method b() has to execute() after method a().

If your language does not provide a mechanism to define these kinds of pre-conditions, you need to implement one yourself.

I agree with you that to implement this extra functionality (or these specific class contract features) inside RemoteTool() class could degrade your current design. A simple solution could be use another class with the responsibility of enforce the needed pre-condition before call the specific method of RemoteClass.(RemoteToolProxy() can be a suitable name)

This way you will decouple the concrete functionality and the contract that says how to use it.

There are other alternatives provided by a software design approach called Design by Contract that can give you other ways of improving your class contract.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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