【问题标题】:How should a service which needs to be stoppable, but not by clients, be stopped?应该如何停止需要可停止但不能由客户端停止的服务?
【发布时间】:2011-01-20 10:36:57
【问题描述】:

简单的答案是拥有一个包含所有常规操作的接口,其中还包括一个 stop() 方法。

interface Service {
   operation( parameters ...);
   somethingElse( parameters ... );

   stop();
}

stop 方法的主要问题是大多数获得服务引用的客户端可能也不应该能够停止服务。

另一种选择是简单地定义两个接口,服务和可停止

interface Service {
    operation( parameters ...);
    somethingElse( parameters ... );
}

interface Stoppable {
    void stop();
}

这种方法的唯一问题是,如果实现被另一个 Service 包装,那么 stop 方法就会被隐藏起来。

原来阻止客户端“停止”你的服务的问题仍然是可能的,他们只需要先检查引用是否是 Stoppable 的实例,然后他们就可以“停止”它。

你会如何解决这个问题?

我有一个想法可以优雅地解决问题(对我来说很好),而无需留下公共站点。不过,在我展示之前,我想要一些想法。

【问题讨论】:

  • 我很想知道您对问题的优雅解决方案。

标签: java design-patterns class-diagram


【解决方案1】:

使用接口继承:

interface Service {
    operation( parameters ...);
    somethingElse( parameters ... );
}


interface StoppableService extends Service {
    void stop();
}

只需要原始服务的客户端通过适当的工厂方法获得。任何应该能够停止服务的东西,请求 StoppableService。

如果您担心转换为 StoppableService 的客户端会调用 stop(),那么您将需要具体的实现来分离此函数。给他们一个具体的实现,它有一个无操作版本的 stop()。您仍然可以让您的工厂为应该能够停止它的任何人提供 stop() 的工作实现。也许当他们要求您的工厂实施时,他们可以传递适当的凭据,以便您确定他们应该能够做什么并为他们提供正确的版本。

【讨论】:

  • 你需要为你的最后一段想法提供例子。
  • 如果我理解您的说法,工厂会根据某些魔术凭据返回 Service 或 StoppableService。这是恕我直言的缺陷,因为使用该工厂的任何人都需要服务,将凭据引入这意味着解决方案变得混乱,因为我们现在必须管理哪些凭据足以获得可停止服务。大多数应该能够调用可停止的东西,不关心服务部分,他们只想要一个可停止的,当他们想要停止()它时。将两个不相关的接口混合在一起是不好的做法。
  • 因此,如果您进行一些生命周期处理,您获得的不仅仅是 Stoppable,您的工厂知道实际上提供了两种不同类型的东西——Service 和 Stoppable。糟糕!
  • @mP - 如果您出于给定的原因想要保持 Service 和 Stoppable,这很公平。最初的问题并没有说得特别清楚。我可以帮助解释工厂部分,但鉴于我已经被否决了(我猜是你,如果没有,我很抱歉),我并没有很大的动力这样做。
【解决方案2】:

你可以这样做

interface Service {
    operation( parameters ...);
    somethingElse( parameters ... );

    <E> E getControlInterface(Class<E> clazz);
}

然后

Stoppable stoppable = service.getControlInterface(Stoppable.class);
if (stoppable != null) {
    stoppable.stop();
}

但我认为这过于复杂,实现Stoppable 接口就足够了。包装器应该知道Stoppable 并实现它。

【讨论】:

  • 我的 q 说普通客户不应该能够自己调用 stop()。根据您的建议,他们可以在调用 service.getControlInterface 后调用 stop...
  • 将 Stoppable.class 传递给 getControlInterface 有什么意义?我可以传递其他可能的参数,tehre 应该只是一个答案,所以问它毫无意义。
  • 谁是“常规”,谁不是?您在这里需要某种身份验证和授权。这不是语言问题,也不是设计模式问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多