Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best design practice when you have a class where properties are dependent on a web service call? [closed]

If I have a class with some read-only properties that are populated by a web service call, what is considered the best way to design this?

Is it considered proper for the property getters to make the web service call. It seems that the downside of this is that the getter is doing more than one thing and obscures the expense of the call. I realize that any of the property getters only needs to make the web service call once (by checking for nulls or flag before making the call). But that a single property getter could potentially be setting the private fields for other properties seems to smell to me.

On the other hand if I have have a public method (ie InitWebServiceVals) that calls the web service and updates the private fields I am creating a temporal dependency between the method and the property getters. So the API obscures the fact that you shouldn't read a property until the "InitWebServiceVals" is called.

Or is there some other method or pattern that addresses this? For example, making the webservice call in the constructor? Or is this generally indicative of a design issue?

I have run into this issue a number of times and I always ended up preferring the second method to the first.

Any thoughts?

Seth

like image 299
Seth Spearman Avatar asked Feb 20 '12 16:02

Seth Spearman


4 Answers

I would throw one other option at you. You could use a factory (either a class or static method) to instance your class. The factory would be responsible for making the web service calls and handing off the property values to the class (either through a parameterized constructor on your class that accepts the values, or by declaring the setters as internal).

This would have the added benefit of decoupling the "how does my class get those values" part from the class itself.

So:

var myClass = MyClass.Create(); // where create is a static
// or
var myClass = MyClassFactory.Create(); // using a separate factory
// or
var myClass = MyClass.CreateFromTestData(value1, value2, value3); // etc
like image 141
JMarsch Avatar answered Oct 15 '22 20:10

JMarsch


I would use lazy initializers. There is full support for them baked into the .NET framework. See Lazy(Of T).

like image 33
RB. Avatar answered Oct 15 '22 19:10

RB.


I would say that a form of the Factory Pattern and return the Class from a "Create" type of static method, this allows you to separate the WebService side should you change how you are retrieving the data, from Web Service to Restful etc it also makes it easier to impliment unit testing, asyncronous lazy loading etc as well as testing. You could also easily use an IOC container or Dependency Injection to inject the Service API at runtime.

To clarify the testing, if you define an interface with the Create Method you can simple "swap" or "Inject" out the Interface implementation.

public MyClass webServiceClass = IMyFactoryInterface.Create();

public static MyClassFactory : IMyFactoryInterface
{
    public static MyClass Create(params anyParametersRequired)
    {    
        // Do Something
    }
}
like image 2
Lloyd Avatar answered Oct 15 '22 19:10

Lloyd


In my experience, having property getters (or setters) doing anything computationally expensive is a bad idea. When I see a property, I generally assume that it is going to be a fast, simple operation.

like image 2
Steve Czetty Avatar answered Oct 15 '22 20:10

Steve Czetty