前提
现有代码库(不太可能更改):
public interface Shape {
void print();
}
并使用(圆形,三角形,正方形等)的实现方式:
public final class Circle implements Shape {
private final CircleInput input;
public Circle(CircleInput input) {
this.input = input;
}
@Override
public void print() { ... }
}
CircleInput
,TriangleInput
和SquareInput
根本不相关(不相交的类型)。问题
输入对象可能非常复杂,我希望用户创建一个封装他们自己的业务逻辑的类。我探索了两种方法,但是它们都很笨拙,这使我不得不思考是否我错误地解决了该问题,并且有使用Java的更好方法。
选项1
我考虑过定义一个通用接口:
public interface ShapeInput<T> {
T getInput();
}
用户然后可以创建:
public final class MyCircleInput<CircleInput> {
private final ShapeDependency shapeDependency;
@Inject
MyCircleInput(ShapeDependency shapeDependency) {
this.shapeDependency = shapeDependency;
}
@Override
public CircleInput getInput() {
return createCircleInput(shapeDependency);
}
// ... very complex business logic ...
private static CircleInput createCircleInput(
ShapeDependency shapeDependency) {
// returns a CircleInput
}
}
然后使用ShapeFactory根据类型创建正确的实例。但是我不能说
ShapeInput<CircleInput | TriangleInput>
,要强制执行此行为,需要运行时检查。选项2
我可以直接在
Shape
上使用继承:public abstract class AbstractShape implements Shape {
protected final Shape shapeImpl;
public AbstractShape(CircleInput input) {
this.shapeImpl = new Circle(input);
}
public AbstractShape(TriangleInput input) {
this.shapeImpl = new Triangle(input);
}
// Proxies print() to the underlying impl.
@Override
public void print() {
return shapeImpl.print();
}
}
用户可以创建:
public final MyCircle extends AbstractShape {
@Inject
MyCircle(ShapeDependency shapeDependency) {
super(createCircleInput(shapeDependency));
}
// ... very complex business logic ...
private static CircleInput createCircleInput(
ShapeDependency shapeDependency) {
// returns a CircleInput
}
}
最佳答案
因此,在此系统中,已经很好地定义了Circle
,Square
,Triangle
(均为Shape
)以及它们各自的输入CircleInput
,SquareInput
和TriangleInput
(不相交)。 ?
用户为什么要扩展所有这些输入?
您的管道本质上是否不是某些业务逻辑根据ShapeDependency
来创建ShapeInput
并将其传递给正确的Shape
的管道?
您可以通过明确定义每个班级的职责来澄清这一点。我希望CircleInput
,SquareInput
等的唯一责任是仅保存输入数据,而不执行业务逻辑。
我会将业务逻辑保留在自己的类中,也许是这样的:
abstract class BusinessLogic<S extends Shape, I> {
private final Function<I, S> shapeConstructor;
public BusinessLogic(Function<I, S> shapeConstructor) {
this.shapeConstructor = shapeConstructor;
}
protected abstract I createShapeInput(ShapeDependency shapeDependency);
public final S createShape(ShapeDependency shapeDependency) {
I shapeInput = createShapeInput(shapeDependency);
S shape = shapeConstructor.apply(shapeInput);
return shape;
}
}
class CircleBusinessLogic extends BusinessLogic<Circle, CircleInput> {
public CircleBusinessLogic() {
super(Circle::new);
}
@Override
protected CircleInput createShapeInput(ShapeDependency shapeDependency) {
return new CircleInput();
}
}
让我知道这是否满足您的要求。如果没有,请说明您的目标和渠道。