《务实程序员》的练习 26
public class Colada {
private Blender myBlender;
private Vector myStuff;
public Colada() {
myBlender = new Blender();
myStuff = new Vector();
}
private doSomething() {
myBlender.addIngredients(myStuff.elements());
}
}
这遵循德墨忒尔定律/最少知识原理。
将其替换为以下利用依赖注入的内容是否更好,是否有任何警告?
public class Colada throws IllegalArgumentException {
private Blender myBlender;
private Vector myStuff;
public Colada(Blender blender, Vector stuff) {
if (null == blender) {
throw new IllegalArgumentException()
} else {
myBlender = blender;
}
if (null == stuff) {
throw new IllegalArgumentException()
} else {
myStuff = stuff;
}
}
public static Colada createDefaultInstance() {
Blender blender = new Blender();
Vector stuff = new Vector();
return new Colada(blender, stuff);
}
private doSomething() {
myBlender.addIngredients(myStuff.elements());
}
}
There is a code snippet presented in The Pragmatic Programmer on page 143 as:
public class Colada {
private Blender myBlender;
private Vector myStuff;
public Colada() {
myBlender = new Blender();
myStuff = new Vector();
}
private doSomething() {
myBlender.addIngredients(myStuff.elements());
}
}
This obeys the Law of Demeter / Principle of Least Knowledge.
Is it preferable to, and are there any caveats for, replacing it with the following, which utilises Dependency Injection?
public class Colada throws IllegalArgumentException {
private Blender myBlender;
private Vector myStuff;
public Colada(Blender blender, Vector stuff) {
if (null == blender) {
throw new IllegalArgumentException()
} else {
myBlender = blender;
}
if (null == stuff) {
throw new IllegalArgumentException()
} else {
myStuff = stuff;
}
}
public static Colada createDefaultInstance() {
Blender blender = new Blender();
Vector stuff = new Vector();
return new Colada(blender, stuff);
}
private doSomething() {
myBlender.addIngredients(myStuff.elements());
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
public getInstance(),不应该是“public static Colada getInstance()”吗?
在我的世界里,两者都很好,第一个更具可读性,第二个更具活力。但他们都没有表明 myBlender 和 myStuff 是属性,因此很难理解为什么您更喜欢它动态。但如果这就是你想要的,看起来没问题。不过,我只是创建两个构造函数,而不是 getInstance,一个没有参数,如第一个示例,另一个有两个,如第二个
Cheers
Nik
public getInstance(), shouldn't that be "public static Colada getInstance()"?
Both are fine in my world, the first one more readable, the second one more dynamic. But neither of them suggest that myBlender and myStuff are properties, thus it's hard to see why you'd prefer it dynamic. But if that's what you want, it looks all right. Instead of getInstance I'd just make two constructors, though, one with no arguments like the first example and one with two like the second
Cheers
Nik
如何构建对象的创建是一个单独的问题,而不是它公开的API。
德墨忒尔定律讲述了类的 API,而不是它们的构造方式,因此我认为构造函数注入与德墨忒尔定律之间没有冲突。
也就是说,一旦决定使用依赖注入,在创建对象时就应该小心避免歧义。如果您继续提供无参数构造函数或静态工厂方法,人们可能会使用它而不是让外部调用者组成依赖层次结构。
每当开发人员通过使用工厂方法(或无参数构造函数)意外破坏依赖层次结构时,他们就会在此时引入紧耦合。当您决定使用 DI 时,您可以通过持续这样做获得最大的好处。
How you structure creation of objects are a separate concern than the API it exposes.
The Law of Demeter says something about the API of classes, not how they are constructed, so I see no conflict between Constructor Injection and the Law of Demeter.
That said, once you decide to use Dependency Injection, you should be careful to avoid ambiguity when it comes to creation of objects. If you keep offering a parameterless constructor or a static factory method, people may use this instead of letting the external caller compose the dependency hierarchy.
Every time developers accidentally break the dependency hierarchy by using the factory method (or paramterless constructor) they introduce a tight coupling at that point. When you decide to use DI, you can best harvest the benefits from doing so consistently.