1

考虑到“务实的程序员”中的练习,我有一些问题。

它说:

1.

public void showBalance(BankAccount acct) {
Money amt = acct. getBalance() ;
printToScreen(amt .printFormat()) ;
}

变量 acct 作为参数传入,因此允许调用 getBalance。然而,调用 amt.printFormat() 不是。我们不“拥有”amt,它也没有传递给我们。

但是我们确实拥有amt 对吗?它在方法和 LOD 中声明:当您的方法创建本地对象时,该方法可以调用本地对象上的方法。

这个例子是否打破了 LOD?在我看来,不是吗?

2.

public class Colada {
private Blender myBlender;
private Vector myStuff;

public Colada() {
myBlender = new Blender();
myStuff = new Vector() ;
}

private void doSomething() {
myBlender.addlngredients(myStuff.elements());
}
}

由于 Colada 创建并拥有 myBlender 和 myStuff,因此允许调用 addIngredients 和元素。

现在我不明白为什么允许 doSomething 调用 myBlender 和 myStuff ,因为它没有创建它。

3.

void processTransaction(BankAccount acct, int) {
Person *who;
Money amt;
amt.setValue(123.45);
acct.setBalance(amt);
who = acct .getOwner() ;
markWorkflow(who->name(), SET_BALANCE);
} 

在这种情况下,processTransaction 拥有 amt,它是在堆栈上创建的,acct 是传入的,因此 setValue 和 setBalance 都是允许的。但是 processTransaction 不拥有谁,所以调用 who->name() 是违规的。

所以在这里它确实声明了谁,但不允许调用它。也许我误解了“拥有”的概念。

有人可以澄清一下吗?

谢谢

4

1 回答 1

2

让我们一一来看看所谓的矛盾。

1.

public void showBalance(BankAccount acct) {
    Money amt = acct. getBalance() ;
    printToScreen(amt .printFormat()) ;
}

The variable acct is passed in as a parameter, 
so the getBalance call is allowed. 
Calling amt.printFormat(), however, is not. 
We don't "own" amt and it wasn't passed to us.

这个声明是完全有效的,因为 LoD 声明虽然acct可以传递给showBalance()并且showBalance()可以访问getBalance()由于直接引用acct,它可能不会在 的任何实例上调用任何方法Money。这是因为没有类型的对象Money被传递给showBalance(),它只是通过本地访问器引用它。这并不意味着amt现在拥有showBalance().

2.

public class Colada {
    private Blender myBlender;
    private Vector myStuff;

    public Colada() {
        myBlender = new Blender();
        myStuff = new Vector() ;
    }

    private void doSomething() {
        myBlender.addlngredients(myStuff.elements());
    }
}

Since Colada creates and owns both myBlender and myStuff, 
the calls to addIngredients and elements are allowed .

现在,在这个类构造函数中发生的是 aBlender和一个Vector对象的声明和实例化。myBlender因此, and的所有者myStuff是类Colada。LoD 声明m对象的方法o可以访问 的所有直接组件o,因此在这种情况下,方法可以直接doSomething()访问Colada的组件,并且它可以调用和的方法Blender和。VectormyBlendermyStuff

3.

void processTransaction(BankAccount acct, int) {
    Person *who;
    Money amt;
    amt.setValue(123.45);
    acct.setBalance(amt);
    who = acct .getOwner() ;
    markWorkflow(who->name(), SET_BALANCE);
}

In this case, processTransaction owns amt, 
it is created on the stack, acct is passed in, 
so both setValue and setBalance are allowed. 
But processTransaction does not own who, 
so the call who->name() is in violation.

该方法processTransaction()接收对象中的银行帐户acct。它初始化一个 type 的对象Money,设置值,然后调用setBalance()acct 上的 setter 方法,这与 LoD 是一致的。由于amt是在里面创建和初始化的processTransaction,所以访问setValueofamt也是符合LoD的。现在矛盾来了。*who只是一个指向类型对象的指针Person,它只能通过访问器方法看到getOwner。但该方法归 拥有acct,因此调用方法*who无效,因为它会破坏 LoD。

简而言之,LoD 状态a.getB().getC().doSomething()无效,只有a.getB()有效。如果我必须用简单的英语写 LoD,可以用 3 个单词指定 - Chain Of Command

假设层次结构 其中Object A包含 的实例Object B,并且Object B包含 的实例Object C,根据 LoD,以下情况成立。

  • 对象 A 不能通过对象 B 的实例访问和更改对象 C。
  • 但是,对象 B 可以根据可以从对象 A 获取的某些标准访问和更改对象 C。

我希望这能消除你的疑虑。

于 2013-02-06T00:16:10.043 回答