开发者

Designing service start interface

The simple answer is of course to include a start method on the Service interface.

interface Service {
   void start();
   OperationResult operation( parameters );
   ...
}

This of course sux because most users of the Service don't want or care about starting the service they just want to use methods like operation.

How would you solve this problem? I have a simple solution which does have one major limitation without polluting the Service开发者_开发问答 interface thus I would like to hear of peoples proposals.


If it's necessary to start a service, then do stuff with it, and then perhaps terminate the service, there should be an object whose function is simply to start the service and supply an object which may then be used to do stuff with the service, including terminate it (the latter action--probably best handled via IDisposable--should invalidate the "do-stuff" object).


A few ways:

  • start it whenever it gets constructed
  • throw an exception from operation methods if the service isn't started, indicating improper usage
  • automatically start it from every method, if it isn't started


Your question arises because you are mixing implementation issues (start() method, e.g.) with the actions (operation() method). Start is an implementation issue because you could create an instance for each caller or you can have a singleton (as in cached instances). The caller should not have to call the method at all. In fact, if you keep the start method and change your implementation to a singleton tomorrow, the code may stop working for the existing clients.

IMO, you should get rid of the start method from this interface and let the caller worry about delegating the task that your operation method does best.

If you push the start method (an optimization step that has nothing to do with the interface) to your implementation, you can solve the problem in any number of ways. For example,

a. call start() if it has not been called before in operation() method. You will need to deal with synchronization issues. b. call start() in the constructor of your implementation object and be done with it.

etc.


If you don't want the consumer to care about calling a startup. You can consider delegate your startup code internally to a protected method that lazy initializes what you are currently doing this on startup. Such as:

    protected MyService getMyService() {
    if(myService == null) {
        myService = new MyServiceImpl();
        myService.startup();
    }
    return idpPersistence;
}

Call methods like this:

public String findByThis(String tag, String key) {
    return getMyService().findThat(MyClass.class, column, key);
}

This of course has some tradeoffs. If you service is expensive on startup, then the first caller well take that hit first.

Another option is to implement these using a static{} block but that's of course sometimes not very testable as well. Also, doing your startup routines on object consturction, which sometimes violates IOC patterns as well. I went with adding a Service interface because the clients I had were internal, and I wanted all services initialized and ready on startup.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜