固有紧耦合设计中的依赖注入和 IoC 实践
Dependency Injection and IoC practices in a inherently tight coupling design
处理如下情况的最佳实践是什么(简化的符号类比案例,不要求特定的实施解决方案):
假设我想创建一个自定义 class 来代表我办公室桌面上的物理日历。它可以在 Java 中翻译为 GregorianCalendar(myCustomZone)。
所以,我创建了一个 class 例如:
class MyOfficeCalendar extends GregorianCalendar{
public MyOfficeCalendar(){
super(new SimpleTimeZone(...));
}
}
在这些情况下,代码审阅者会说在构造函数中实例化是个坏主意。但是,如果我将 SimpleTimeZone 依赖项注入构造函数,这在我看来很容易出错,
因为我的依赖只应该以所需的方式实例化。我想要在那个范围内进行控制,而不是暴露错误注入的可能性。我的意思是,某些实例化是我的调用者 class 行为或范例的一部分。 MyOfficeCalendar 的定义恰好是一个 GregorianCalendar 与这个特定的自定义 TimeZone 实例一起工作。
那么通常在这些情况下最好的设计是什么?
强制 MyCalendar 对其他非预期用途足够灵活,这可能使其不连贯并依赖于正确的 IoC 容器 xml 或共享的开发用户误解,因为我不是强迫任何事情
在构造函数中实例化绝对所需的依赖
在没有方便的 OOP 的情况下管理整个事情 class(我喜欢
尽我所能遵守单一职责原则)
改变整个架构?
引入一个构建器来封装构建行为。例如
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。
处理如下情况的最佳实践是什么(简化的符号类比案例,不要求特定的实施解决方案):
假设我想创建一个自定义 class 来代表我办公室桌面上的物理日历。它可以在 Java 中翻译为 GregorianCalendar(myCustomZone)。
所以,我创建了一个 class 例如:
class MyOfficeCalendar extends GregorianCalendar{
public MyOfficeCalendar(){
super(new SimpleTimeZone(...));
}
}
在这些情况下,代码审阅者会说在构造函数中实例化是个坏主意。但是,如果我将 SimpleTimeZone 依赖项注入构造函数,这在我看来很容易出错, 因为我的依赖只应该以所需的方式实例化。我想要在那个范围内进行控制,而不是暴露错误注入的可能性。我的意思是,某些实例化是我的调用者 class 行为或范例的一部分。 MyOfficeCalendar 的定义恰好是一个 GregorianCalendar 与这个特定的自定义 TimeZone 实例一起工作。
那么通常在这些情况下最好的设计是什么?
强制 MyCalendar 对其他非预期用途足够灵活,这可能使其不连贯并依赖于正确的 IoC 容器 xml 或共享的开发用户误解,因为我不是强迫任何事情
在构造函数中实例化绝对所需的依赖
在没有方便的 OOP 的情况下管理整个事情 class(我喜欢 尽我所能遵守单一职责原则)
改变整个架构?
引入一个构建器来封装构建行为。例如
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。