我正在全神贯注于如何最好地设计我正在使用的系统。
假设它是类似于典当行的应用程序。我已经将购买和转售流程限制为一种称为ExecutionStrategy的流程。此应用程序中有四个ExecutionStrategy实现:注册客户,投标和购买,定价以及过帐到商店。
每一项策略都遵循一个基本步骤,包括主要执行工作流程并记录我们在数据存储区中所做的工作。
除了这些投标,购买以及定价外,还需要专家咨询,然后我们才能在执行工作流中执行任何操作。
在这里,我对我想根据设计做出的决定感到有些困惑。似乎有三个选项可供选择,我不太确定哪个是最正确的。 1)使用带有ExecutionStrategyWithConsultation的ExecutionStrategy之类的东西来扩展执行策略,该策略将策略的执行工作流程包装为咨询阶段。 2)为ExecutionStrategy创建Decorator模式,并使用ConsultationServiceDecorator之类的方式扩展它。 3)在购买/投标和定价的实现中创建一个成员变量,以随时通过围绕该服务的接口调用咨询服务。
我将在下面概述设计。
一些注意事项:
T consultOn(T item)
上述每种方法的优点/缺点:
直接扩展执行策略:
PurchasingExecutionStrategy extends ExecutionStrategyWithConsultation
这样的代码,我们有了一个了解,因此,我们从中了解到它只是一种什么样的工作流程。创建装饰器:
PurchasingExecutionStrategy extends ExecutionStrategyWithConsultation
获得的知识,除非我们将PurchasingExecutionStrategy
实际实例化为ConsultationServiceDecorator
的构造函数arg的地方使用接口创建成员变量:
每个示例:
//Number 1
public interface ExecutionStrategy<T> {
/**
* Perform the main execution workflow
*/
public T execute(T item);
}
public interface ConsultationService {
public StoreItem consultOn (StoreItem item);
}
public abstract class ExecutionStrategyWithConsultation implements ExecutionStrategy<StoreItem> {
protected ConsultationService consultationService;
}
public class ListingExecutionStrategy extends ExecutionStrategyWithConsultation {
public StoreItem execute(StoreItem item) {
if (item.hasDirectBuyer()) { //hasDirectBuyer is populated by ConsultationService
item.sellTo = item.directBuyer.getId();
} else {
//no direct buyer
SuggestedPriceRange priceRange = item.getConsultationPriceRange(); //consultationPriceRange is populated by ConsultationService
item.priceRange = priceRange;
item.listToWebsite = true;
}
return item;
}
}
//Number 2
public interface ExecutionStrategy<T> {
/**
* Perform the main execution workflow
*/
public T execute(T item);
}
public abstract class ExecutionStrategyDecorator<T> implements ExecutionStrategy<T>{
protected final ExecutionStrategy<T> executionStrategy;
public ExecutionStrategyDecorator(ExecutionStrategy<T> execStrategy) {
executionStrategy = execStrategy;
};
}
public class ExecutionStrategyWithConsultation extends ExecutionStrategyDecorator<StoreItem> {
protected ConsultationService consultationService;
public ExecutionStrategyWithConsultation(ExecutionStrategy<StoreItem> execStrat, ConsultationService service) {
super(execStrat);
consultationService = service;
}
public StoreItem execute(StoreItem item) {
StoreItem itemAfterConsultation = consultationService.consultOn(item);
return execStrategy.execute(itemAfterConsultation);
}
}
public class ListingExecutionStrategy implements ExecutionStrategy<StoreItem> {
public StoreItem execute(StoreItem item) {
if (item.hasDirectBuyer()) { //hasDirectBuyer is populated by ConsultationService
item.sellTo = buyer.getId();
} else {
//no direct buyer
SuggestedPriceRange priceRange = item.getConsultationPriceRange(); //consultationPriceRange is populated by ConsultationService
item.priceRange = priceRange;
item.listToWebsite = true;
}
return item;
}
}
public class ListingExecutionStrategyFactory {
public ExecutionStrategy instantiate() {
return new ExecutionStrategyWithConsultation(new ListingExecutionStrategy(), new ConsultationServiceImpl());
}
}
//Number 3
public interface ExecutionStrategy<T> {
/**
* Perform the main execution workflow
*/
public T execute(T item);
}
public interface ConsultationService {
public DirectBuyer getDirectBuyerIfExists(StoreItemType itemType);
public SuggestedPriceRange getSuggestedPriceRange(StoreItem item);
}
public class ListingExecutionStrategy implements ExecutionStrategy<StoreItem> {
ConsultationService service;
public PurchasingExecutionStrategy(ConsultationService consultService) {
service = ConsultationService;
}
public StoreItem execute(StoreItem item) {
DirectBuyer buyer = service.getDirectBuyerIfExists(item.getItemType())
if (Optional.ofNullable(buyer).isPresent()) {
item.sellTo = buyer.getId();
return item;
} else {
//no direct buyer
SuggestedPriceRange priceRange = service.getSuggestedPriceRange(item);
item.priceRange = priceRange;
item.listToWebsite = true;
return item;
}
}
}
感谢您的输入。感谢帮助。
答案 0 :(得分:1)
作为ConsultationService的替代方法,您可以考虑构建ExecutionService实例链以允许创建复杂的处理方案:
public interface ExecutionStrategy<T> {
public T execute(T item);
}
public interface ExecutionStrategyChain<T> extends ExecutionStrategy<T> {
public static <T> ExecutionStrategyChain<T> newInstance(ExecutionStrategy<T> executionStrategy) {
return new ExecutionStrategyChainImpl<T>(executionStrategy);
}
public ExecutionStrategyChain<C> chainTo(ExecutionStrategy<C> executionStrategy);
}
public abstract class AbstractExecutionStrategyChain<T> implements ExecutionStrategyChain<T> {
protected AbstractExecutionStrategyChain() {
this(null);
}
public abstract T execute(T item);
public ExecutionStrategyChain<T> chainTo(ExecutionStrategy<T> executionStrategy) {
return new ExecutionStrategyChainImpl<T>(this, executionStrategy);
}
}
public final class ExecutionStrategyChainImpl<T> extends AbstractExecutionStrategyChain<T> {
private final ExecutionStrategy<T> firstExecutionStrategy;
private final Executionstrategy<T> secondExecutionStrategy;
public ExecutionStrategyChainImpl(ExecutionStrategy<T> first, ExecutionStrategy<T> second) {
if(first == null) throw new NullPointerException();
this.firstExecutionStrategy = first;
this.secondExecutionStrategy = second;
}
public ExecutionStrategyChainImpl(ExecutionStrategy<T> first) {
this(first, null);
}
@Override
public final T execute(T item) {
if(item == null) {
return null;
}
T result = firstExecutionStrategy.execute(item);
if(result != null && secondExecutionStrategy != null) {
result = secondExecutionStrategy.execute(result);
}
return result;
}
}
public class PreProcessor<T> implements ExecutionStrategy<T> {
public PreProcessor() {
}
@Override
public T execute(T item) {
//Do some pre-processing of item
return item;
}
}
public class PostProcessor<T> implements ExecutionStrategy<T> {
public PostProcessor() {
}
@Override
public T execute(T item) {
//Do some post-processing of item
return item;
}
}
public class MyNormalProcessor<T> extends AbstractExecutionStrategyChain<T> {
public MyNormalProcessor() {
}
@Override
public T execute(T item) {
//Do something normal with the item
return item;
}
}
public static final ExecutionStrategy<StoreItem> COMPLEX_EXECUTION_STRATEGY =
ExecutionStrategyChain<StoreItem>.newInstance(new PreProcessor<StoreItem>())
.chainTo(new MyNormalProcessor<StoreItem>())
.chainTo(new PostProcessor<StoreItem>());