当前位置: 首页 > 知识库问答 >
问题:

带有命令模式的springbeans映射

张唯
2023-03-14

我有不同实现的< code>ProductHandler类,例如< code>ABCProductHandler、< code>DEFProductHandler等..它们是使用如下所示的命令模式从< code>ProductServiceImpl类调用的。

产品ServiceImpl类:

@Service
public class ProductServiceImpl implements ProductService {

    private Map<ProductType,ProductHandler> productHandlersMap = 
                                         new EnumMap<>(ProductType.class);

    private ABCProductHandler abcProductHandler;

    private DEFProductHandler defProductHandler;

    //....10 other product handlers goes here

    @Autowired
    public ProductServiceImpl(ABCProductHandler abcProductHandler, 
                                  DEFProductHandler defProductHandler, .....) {
        this.abcProductHandler = abcProductHandler;
        this.defProductHandler = defProductHandler;
        //....10 other product handlers goes here
    }

    @PostConstruct() 
    public void init() {
        productHandlersMap.put(ProductType.ABC, abcProductHandler);
        productHandlersMap.put(ProductType.DEF, defProductHandler);
        //....10 other product handlers goes here
    }

    @Override
    public ProductDetails calculateProductPrice(ProductType productType) {
        productHandlersMap.get(productType).calculate();
        //..some otehr code goes here
        return productDetails;
    }
}

但是,我对上面的 ProductServiceImpl 类不满意,因为有很多带有样板代码的产品处理程序Map.put 调用。

现在,我的问题是,有什么方法可以轻松加载productHandlersMap

@Service
public class ProductServiceImpl implements ProductService {

    private Map<ProductType,ProductHandler> productHandlersMap = 
                        new EnumMap<>(ProductType.class);

    @PostConstruct() 
    public void init() {
         //How to laod productHandlersMap easily with 
         // different ProductHandler types here?
    }

    @Override
    public ProductDetails calculateProductPrice(ProductType productType) {
        productHandlersMap.get(productType).calculate();
        //..some other code goes here
        return productDetails;
    }
}

共有2个答案

顾池暝
2023-03-14

您可以创建Spring配置组件

@Configuration
public class CollectionConfig {

    @Bean
    public ProductHandler  getABC() {
        return new ABCProductHandler(ProductType.ABC);
    }

    @Bean
    public ProductHandler  getDEF() {
        return new DEFProductHandler(ProductType.DEF);
    }

    @Bean
    public ProductHandler  getXYZ() {
        return new XYZProductHandler(ProductType.XYZ);

    }
 

    // other factory methods

}

之后:

    @Service 
public class ProductServiceImpl implements ProductService { 
private Map<ProductType,ProductHandler> productHandlersMap = new EnumMap<>(ProductType.class); 

 @Autowired(required = false)
 private List<ProductHandler> beanList;

 @PostConstruct() 
public void init() { 
    beanList.foreach(b->
    productHandlersMap.put(b.getType(), b))
     }
}
公西马鲁
2023-03-14

Spring可以将实现接口< code>I的bean的不同实现自动连接到< code>Map类型的属性

public enum ProductType {
    ABC(ProductType.ABC_BEAN_NAME),
    DEF(ProductType.DEF_BEAN_NAME);

    public static final String ABC_BEAN_NAME = "abcProductHandler";
    public static final String DEF_BEAN_NAME = "defProductHandler";

    private String beanName;

    ProductType(String beanName) { this.beanName = beanName; }

    public String beanName() { return beanName; }
}

然后,在@Configuration工厂类中或通过@Service annotation定义不同的

@Service(ProductType.ABC_BEAN_NAME)
public class ABCProductHandler implements ProductHandler {

    // ...
}

@Service(ProductType.DEF_BEAN_NAME)
public class DEFProductHandler implements ProductHandler {

    // ...
}

现在,在您的< code > ProductServiceImpl bean中,只需自动连接一个< code >映射

@Service
public class ProductServiceImpl implements ProductService {

    private final Map<String, ProductHandler> productHandlersMap;

    @Autowired
    public ProductServiceImpl(Map<String, ProductHandler> productHandlersMap) {
        this.productHandlersMap = productHandlersMap;
    }

    @Override
    public ProductDetails calculateProductPrice(ProductType productType) {
        productHandlersMap.get(productType.beanName()).calculate();
        //..some otehr code goes here
        return productDetails;
    }
}

这样,您可以让Spring完成所有的注入工作,甚至不需要使用< code>@PostConstruct方法。

请注意< code > calculate product price 方法中< code > product type . bean name()的使用。这确保您使用正确的bean来计算价格。

 类似资料:
  • 嗯,我正在尝试实现命令模式来创建与对象的交互。 几乎所有要创建的命令都由对一个对象的请求和该对象的响应组成。 所以问题是——如何管理这些回应? 当所有命令都无效时,这很容易制作。无论它们是什么,如果它们实现@executable@接口,您都可以执行它们,因此 无效执行(对象参数) 但是,当他们的反应有不同的类型时,该怎么办?也许命令模式不适合这个项目?

  • 我有一个这样的可重装武器类: 具有以下: 并像这样使用它: 客户: 我想知道,对于命令,对于我看到的示例,除了命令正在操作的对象之外,没有其他。 此示例更改执行方法以允许使用参数。 另一个示例,更接近我在这里拥有的,在构造函数中使用参数。 在命令中包含参数是不是不好的做法/代码气味,在这种情况下是带有项目符号数的?

  • 主要内容:介绍,实现,Order.java,Stock.java,BuyStock.java,SellStock.java,Broker.java,CommandPatternDemo.java命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。 介绍 意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。 主要解决

  • 命令模式 亦称:动作、事务、Action、Transaction、Command 意图 命令模式是一种行为设计模式, 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。 问题 假如你正在开发一款新的文字编辑器, 当前的任务是创建一个包含多个按钮的工具栏, 并让每个按钮对应编辑器的不同操作。 你创建

  • 命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。 介绍 意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。 主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记

  • 问题 你需要让另一个对象处理你自己的可执行的代码。 解决方案 使用 Command pattern 传递函数的引用。 # Using a private variable to simulate external scripts or modules incrementers = (() -> privateVar = 0 singleIncrementer = () ->