gpt4 book ai didi

java - 使用什么设计模式或架构来覆盖默认类实例化或创建

转载 作者:太空宇宙 更新时间:2023-11-04 06:48:09 26 4
gpt4 key购买 nike

我正在编写一个平台,它向开发人员提供一组默认的模块,我希望它们能够扩展以在运行时提供更多自定义功能。以下代码片段是默认的模块层次结构:

package com.test.core;
public abstract class Module {
public abstract void performAction();
}

package com.test.fun;
public class AModule extends Module {

@Override
public void performAction() {
// Perform action A
}
}

package com.test.fun;
public class BModule extends Module {

@Override
public void performAction() {
// Perform action B
}
}

package com.test.fun;
public class CModule extends Module {

@Override
public void performAction() {
// Perform action C
}
}

有一个模块引擎,它将在应用程序实例启动时创建模块,并将这些模块存储在 HashMap 中,其中 [key=name;值=模块]。由于我的后端和应用程序的性质,我必须使用名称作为 key 并识别模块。

public Module createModule(String name) throws Exception {
Module module = null;
Class moduleClass = null;

// Find class by name, default to using <name>Module as the class name
// might throw exception
String className = name = "com.test.fun." + name + "Module";
moduleClass = Class.forName(className);

if (moduleClass == null) {
// quit, nothing to do
} else {
// create the module
module = (QPComponent) moduleClass.getConstructor().newInstance();
}

return module;
}

假设 AModule 是一个二进制文件,并且我无法更新其实现,我想使用键“A”向模块添加更多行为,如下所示。

package com.test.custom;
public class ExtendedModuleA extends AModule {
@Override
public void performAction() {
super.performAction();
// Do some more to add behaviour to AModule
}
}

我必须如何修改架构才能使开发人员能够注册键“A”的模块的自定义实现,以便应用程序启动时,应用程序将获取自定义的 ExtendedModuleA 版本而不是默认的 AModule 版本?

我想的一种方式,看起来不太漂亮,如下:

public class ModuleRegistry {

// Assume singleton
HashMap<String, Class<Module>> registry;

public ModuleRegistry() {

}

private void init() {
registry = new HashMap<String, Class<Module>>();

registry.put("A", ExtendedModuleA.class);
// no extension for B
registry.put("C", CModuleExtra.class);

// developers add more entries to "register" more extended modules here for the future
}



public Class<Module> getExtendedModuleClass(String name) {
return registry.get(name);
}
}

是否有设计模式或工具库可以帮助我解决此类问题?我目前只考虑这个解决方案,因为我记得像 Spring 或 Dagger 或 Android 的 list 这样的东西,你必须注册你的类才能被系统使用或拾取。我已经在我的应用程序中使用 Dagger,但我的模块本身需要 ObjectGraph,因此可能会出现先有鸡还是先有蛋的 catch-22 情况。

最佳答案

您需要检查Decorator Pattern ,它允许您在运行时为类添加动态行为。这更多地适用于组合而不是继承,就像为类创建包装器一样。这是一个启动示例,只是为了理解主要思想:

abstract class Beverage {
protected final BigDecimal price;
public Beverage(BigDecimal price) {
this.price = price;
}
public BigDecimal getPrice() {
return this.price;
}
}

class Coffee extends Beverage {
public Coffee(BigDecimal price) {
super(price);
}
}

class BeverageWithSugar extends Beverage {
private Beverage beverage;
private static final BigDecimal sugarPrice = new BigDecimal("0.15");
public BeverageWithSugar(Beverage beverage) {
super(sugarPrice);
this.beverage = beverage;
}
@Override
public BigDecimal getPrice() {
//here we add the behavior dynamically
return this.beverage.getPrice().add(sugarPrice);
}
}

class BeverageWithChocolate extends Beverage {
private Beverage beverage;
private static final BigDecimal chocolatePrice = new BigDecimal("1.25");
public BeverageWithChocolate(Beverage beverage) {
super(chocolatePrice);
this.beverage = beverage;
}
@Override
public BigDecimal getPrice() {
//here we add the behavior dynamically
return this.beverage.getPrice().add(chocolatePrice);
}
}

public class BeverageStore {
public static void main(String[] args) {
Coffee coffee = new Coffee(new BigDecimal("0.5"));
//adding chocolate to our coffee
Beverage coffeeWithChocolate = new BeverageWithChocolate(coffee);
//adding sugar to our coffee
Beverage coffeeWithSugar = new BeverageWithSugar(coffee);
//adding both chocolate and sugar to our coffee
Beverage greatCoffee = new BeverageWithChocolate(new BeverageWithSugar(coffee));
System.out.println("Coffee price: " + coffee.getPrice());
System.out.println("Coffee with chocolate price: " + coffeeWithChocolate.getPrice());
System.out.println("Coffee with sugar price: " + coffeeWithSugar.getPrice());
System.out.println("Coffee with chocolate and sugar price: " + greatCoffee.getPrice());
}
}

打印:

Coffee price: 0.5
Coffee with chocolate price: 1.75
Coffee with sugar price: 0.65
Coffee with chocolate and sugar price: 1.90

要查看Java框架中如何使用装饰器模式等,请参阅Examples of GoF Design Patterns in Java's core libraries

关于java - 使用什么设计模式或架构来覆盖默认类实例化或创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23700466/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com