我有不同实现的< 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;
}
}
您可以创建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))
}
}
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 = () ->