我正在尝试使用OSGI framewrok构建天气应用。我创建了一个由消费者和提供者组成的国家搜索器,以及一个由消费者和提供者组成的城市搜索器,最后是天气提供者和消费者。
我无法理解如何将天气包与国家和城市包链接
答案 0 :(得分:2)
我认为关键的见识是凝聚力。在您的描述中,您混合了应用程序的不同方面。即您将用户交互(我希望用户..)与查找特定信息的底层机械细节混合在一起。
OSGi的基本思想是将这些部分分为服务。该服务提供了高度内聚的底层功能。即它只做一件事情,一件事情。如果您查看Event Admin服务,则会看到它确实在发布和订阅。这样的想法是,您最终会获得可以做一件事并且与任何其他服务都没有关系(或耦合)的不同服务。这种策略使它们可以在许多不同的应用程序中重用。当您降低内聚力的那一刻,您会发现它们变得更难在其他应用程序中重用。这听起来比实际要容易,它通常需要一些迭代才能获得真正具有凝聚力的服务。
组件是可以提供服务的OSGi物品。通常,组件会消耗其他服务。在您的示例中,您可能有一个包含城市的数据库。为了保持组件的凝聚力,它不应直接操作数据库,而应使用服务。您的组件应该只在城市中是 expert ,但对数据库内容一无所知。每当您编写组件时,就会意识到您正在编写与城市无关的代码,请将其委托给另一项服务。还请确保您的数据库服务不了解城市,而只了解数据库。城市部分是一种非常好用的简便方法,可从完全不了解城市的部分访问城市。
如果您这样想,您最终将获得许多无所作为的服务。您需要在某处协调这些服务。这是应用程序。该应用程序负责整体功能。其目的是将所有松散的末端绑在一起。在您的情况下,它将消耗城市,天气和其他服务。它还将与用户进行交互。为了与用户互动,它需要能够搜索城市。因此,这样的服务接口将很有用:
public interface Geo {
List<String> countries();
List<String> cities(String country);
Country city(String country);
City city(String city);
}
我将您的城市和乡村搜索者结合在一起,因为我发现它们非常具有凝聚力。分解它们会增加复杂性。该服务使我可以在用户界面上创建国家/地区弹出窗口,并可以从选定的国家/地区选择城市。
接下来是气象服务
public interface Weather {
boolean hasWeather( String country, String city);
Report getShortReport(String country, String city);
}
选择国家和城市后,我可以要求气象服务提供报告。
我在这些接口中使用String的原因是为了防止Geo服务和Weather服务之间的耦合。这是我经常看到的主要的菜鸟错误。创建然后在各地(或更糟的是,CityKey)使用的城市和国家(地区)类型,有效地使系统再次成为big ball of mud,其中所有内容都通过某些仅用作String的类与其他内容相关联。 / p>
因此,现在应用程序组件可以选择一个GUI(HTML,gogo,Swing,SWT等)。它可以有效地集中在GUI上,并且低级细节由服务提供商处理。通常,该应用程序应该是系统中任何人都无法重复使用的唯一组件。如果是这样,请将其拆分为可重用部分和特定部分。由于该组件不可重用,因此它是您软件中唯一无需担心耦合的地方。
摘要。这个想法是,如果您查看OGSi应用程序的服务图,那么应该清楚地知道发生了什么,并且应用程序组件(通常不是服务本身)将它们联系在一起。
希望这会有所帮助。
答案 1 :(得分:1)
在捆绑软件之间进行连接的通常方法是OSGi服务。您可以使用接口或类发布服务。然后,使用者可以绑定到接口或类。 在最低级别上,可以使用OSGi API完成此操作,但建议不要直接使用它。 相反,我建议使用带注释的声明式服务。
See the OSGi enroute microservice example。
它显示了内部布线以及使用和提供REST服务。