处理以下情况时的最佳做法是什么(简化的符号类似情况,不要求特定的实施解决方案):
想象一下,我想在办公室桌面上创建一个代表我的物理日历的自定义类。它可以在Java中翻译为GregorianCalendar(myCustomZone)。
所以,我创建了一个类,如:
class MyOfficeCalendar extends GregorianCalendar{
public MyOfficeCalendar(){
super(new SimpleTimeZone(...));
}
}
在这些情况下,代码审查者会说构造函数中的实例化是个坏主意。但是,如果我将SimpleTimeZone依赖项注入构造函数中,这在我看来很容易出错, 因为我的依赖只应该以一种理想的方式实例化。我想在那个范围内控制,而不是暴露错误注射的可能性。我的意思是,某些实例化是我的调用者类行为或范例的一部分。 MyOfficeCalendar的定义恰恰是使用此特定自定义TimeZone实例的GregorianCalendar。
那么在这些情况下通常最好的设计是什么?
强制MyCalendar足够灵活,可以用于其他非预期用途,这可能使其不连贯并依赖于正确的IoC容器xml或共享的开发者 - 用户误解,因为我没有强迫任何东西
在构造函数中实例化绝对期望的依赖
在没有方便的OOP课程的情况下管理整件事(我喜欢 尽可能坚持SingleResponsabilityPrinciple)
更改整个架构?
答案 0 :(得分:1)
引入构建器来封装构造行为。 E.g。
public class MyOfficeCalendar extends GregorianCalendar{
public static class Builder {
private Integer rawOffset;
public void setRawOffset(int rawOffset) {
this.rawOffset = rawOffset;
}
public MyOfficeCalendar build(){
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
int effectiveRawOffset = tz.getRawOffset();
if(rawOffset != null){
effectiveRawOffset = rawOffset;
}
SimpleTimeZone simpleTimeZone = new SimpleTimeZone(effectiveRawOffset, tz.getID());
return new MyOfficeCalendar(simpleTimeZone);
}
}
private MyOfficeCalendar(SimpleTimeZone simpleTimeZone){
super(simpleTimeZone);
}
}
客户端代码只能设置一些SimpleTimeZone
属性。它可以设置多少取决于您的构建器实现。
构建器可以在IoC框架中用作工厂bean。