views:

54

answers:

5

Suppose I have a class that process some data

class SomeClass
{
  public:
    void SetData(IData*);
    void ProcessData(void);
}

The class would need the data to be set before ProcessData() can be called. What are some ways to enforce this dependency? I could return an error code or throw an exception if ProcessData() is called before any data has been passed in. How sound is it to throw an exception?

Additional information Some of the answers suggest passing in the IData to the constructor or ProcessData(). Those are sound answers. The reason why I am not doing this because this part of a GUI system. The user may load in new data to SomeClass any point in time and make modification to it, so during the time when SomeClass is created, the data may not be available.

(Yes, there are better design I could use to avoid this problem, but boss wants to see results on the screen and I have to compromise between good design and visual results).

+4  A: 

Make the SomeClass constructor require IData and remove SetData. Similarly, you could also pass IData to ProcessData.

Taylor Leese
A sound answer; however, I am under some constraint (see additional info within question_
Extrakun
@Extrakun - Can you just disable the button/control that is causing ProcessData to be invoked until the user enters data?
Taylor Leese
Yes, I can, that's a good suggestion. One reason for asking is to see in general cases, is it possible for the class itself to enforce some kind of dependencies contract (if I am using the right terms)
Extrakun
@Extrakun - Keeping the button disabled until the user enters data enforces the contract programmatically. I'd just provide some additional validation logic in ProcessData to throw a relevant exception if for some reason the data (IData) is null.
Taylor Leese
+2  A: 

Make the class take a constructor for the object it needs. Since you cannot call ProcessData without a valid object instance, and you cannot create an instance without providing the object, this solves the problem.

Dave Jarvis
+2  A: 

You can choose to require the data directly in the signature of the ProcessData method. it will thus expose its public contract - need this particular data to work.

class SomeClass
{
  public:
    //void SetData(IData*);
    void ProcessData(IData*);
}

Or you may require the data to be set at the object construction, before any method on that instance can be invoked.

class SomeClass
{
  public:
    SomeClass (IData* data) { SetData (data); }
    void ProcessData(IData*);

  private:
    void SetData(IData*);
}
Developer Art
+2  A: 

Or how about removing SetData and making the process method take the data directly, i.e. ProcessData(IData*) ? If this does not work for you, throwing an exception is by far a better solution than using error codes.

Saulius
A: 

It sounds perfectly well to throw an exception and write about such dependency in documentation. That's what exceptions are for: to make assertions of precondition validity!

Pavel Shved

related questions