简体   繁体   English

设计服务启动界面

[英]Designing service start interface

The simple answer is of course to include a start method on the Service interface. 简单的答案当然是在Service接口上包括启动方法。

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. 这当然很成功,因为大多数服务用户不希望或不关心启动服务,而他们只是想使用诸如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. 我有一个简单的解决方案,它确实有一个主要的限制,而又不会污染服务接口,因此我想听听人们的建议。

如果有必要启动一个服务,然后对其进行填充,然后终止该服务,则应该有一个对象,其功能仅是启动服务并提供一个对象,然后该对象可用于对服务进行填充,包括终止它(后一种操作-最好通过IDisposable处理-应该会使“ do-stuff”对象无效)。

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, eg) with the actions (operation() method). 之所以出现您的问题,是因为您将实现问题(例如start()方法)与操作(operation()方法)混合在一起。 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. 实际上,如果您保留start方法并将明天的实现更改为单例,则该代码可能会停止为现有客户端运行。

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. IMO,您应该从该界面中删除启动方法,并让调用者担心委派您的操作方法最有效的任务。

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. 如果将start方法(与接口无关的优化步骤)推送到实现中,则可以通过多种方式解决该问题。 For example, 例如,

a. 一种。 call start() if it has not been called before in operation() method. 如果以前没有在operation()方法中调用过start(),则调用它。 You will need to deal with synchronization issues. 您将需要处理同步问题。 b. b。 call start() in the constructor of your implementation object and be done with it. 在实现对象的构造函数中调用start()并完成此操作。

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. 另一个选择是使用static {}块来实现这些功能,但是当然有时也不太容易测试。 Also, doing your startup routines on object consturction, which sometimes violates IOC patterns as well. 另外,在对象构造上执行启动例程,这有时也会违反IOC模式。 I went with adding a Service interface because the clients I had were internal, and I wanted all services initialized and ready on startup. 我添加了Service接口,因为我的客户端是内部的,并且我希望所有服务都已初始化并可以在启动时准备好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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