// interface defined in Coffee.jar.
interface Coffee {
void brew();
void discard();
}
// implementation defined in BlackCoffee.jar
class BlackCoffee implements Coffee {
@Override
public void brew() {
System.out.println("Brew BalckCoffee");
}
@Override
public void discard() {
System.out.println("Discard BlackCoffee");
}
}
// implementation defined in FilterCoffee.jar
class FilterCoffee implements Coffee {
@Override
public void brew() {
System.out.println("Brew FilterCoffee");
}
@Override
public void discard() {
System.out.println("Discard FilterCoffee");
}
}
// Runtime class in Coffee.jar
class BrewCoffee {
public static void main(String[] args) {
Coffee coffee = //something here;
coffee.brew();
coffee.discard();
}
}
然后想法是在运行时解析实现而不知道实现。 该应用程序将依赖于 Coffee.jar 以及 BlackCoffee.jar 或 FilterCoffee.jar 之一。
最佳答案
这是依赖注入(inject)框架(如 Spring)的优点之一。
您对接口(interface)进行编码,而您的客户端类不知道在运行时实例化了哪个实现。
您可以根据情况选择 例如在Spring中你可以使用@Conditional属性
@ConditionalOnProperty("coffee.black")
class BlackCoffee implements Coffee
@ConditionalOnProperty("coffee.filter")
class BlackCoffee implements Coffee
然后就有了
@Component
class ClassUsingCoffee {
private Coffee coffee;
@Inject
public ClassUsingCoffee(Coffee coffee) {
this.coffee = coffee;
}
//use coffee as normal
}
然后在 Spring 的属性中,您可以定义属性“black”或“filter”来激活两个具体类实现之一。如果您定义了这两个属性,您会收到一个异常,指出存在 2 个 Coffee 实例,并且它不知道将哪个实例注入(inject)(依赖注入(inject))到您的 ClassUsingCoffee
类
如果不深入了解 Spring 的细节,就很难解释清楚。但是您也可以使用 ApplicationContext
(将其视为包含 Spring 所了解的所有类的“事物”)
class BrewCoffee {
public static void main(String[] args) {
ApplicationContext ctx = //omitted for brevity
Coffee coffee = ctx.getBean(Coffee.class);
coffee.brew();
coffee.discard();
}
在这两个示例中,您都将类耦合到 Coffee
接口(interface),而不是特定的实现。例如如果您执行了 Coffee Coffee = new BlackCoffee()
,那么您的代码将耦合到 Coffee 的特定实现(在本例中为 BlackCoffee
),并且所需的任何更改都需要更改代码(与配置/属性更改相反)
关于java - 解决运行时的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60217989/