1

「実用的なプログラマー」の演習を考慮して、いくつか質問があります。

それは言う:

1.1。

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

変数acctはパラメーターとして渡されるため、getBalance呼び出しが許可されます。ただし、amt.printFormat()の呼び出しはそうではありません。私たちはamtを「所有」しておらず、それは私たちに渡されませんでした。

しかし、私たちamtを所有していますか?これはメソッドで宣言され、LODは次のように述べています。メソッドがローカルオブジェクトを作成するとき、そのメソッドはローカルオブジェクトのメソッドを呼び出すことができます。

この例はLODを壊していますか?私の見方ではありませんか?

2.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とelementsの呼び出しが許可されます。

doSomethingがmyBlenderとmyStuffを作成しなかったため、呼び出しを許可されている理由がわかりません。

3.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を所有していないため、who-> name()の呼び出しは違反しています。

したがって、ここでは誰を宣言しますが、電話をかけることは許可されていません。おそらく私は「所有者」の概念を誤解しています。

誰かがこれを明確にしてくれませんか?

ありがとう

4

1 に答える 1

2

想定される矛盾を一つ一つ見ていきましょう。

1.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()acctMoneyMoneyshowBalance()amtshowBalance()

2.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 .

ここで、このクラスコンストラクターで行われているのは、aBlenderVectorオブジェクトの宣言とインスタンス化です。したがって、との所有者はmyBlenderクラスmyStuffですColada。LoDはm、オブジェクトのメソッドがのoすべての直接コンポーネントにアクセスできると述べているoため、この場合、メソッドdoSomething()はのコンポーネントに直接アクセスでき、のメソッドとonおよびColadaのメソッドを呼び出すことができます。BlenderVectormyBlendermyStuff

3.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。タイプのオブジェクトを初期化し、値を設定してから、LoDに沿ったacctでMoneysetterメソッドを呼び出します。内部で作成および初期化されているsetBalance()ため、のアクセスもLoDに沿っています。今、矛盾が生じます。は、アクセサメソッドを介してのみ表示されるタイプのオブジェクトへのポインタにすぎません。ただし、そのメソッドはによって所有されているため、メソッドを呼び出すとLoDが破損するため、無効になります。amtprocessTransactionsetValueamt*whoPersongetOwneracct*who

つまり、LoDはそれa.getB().getC().doSomething()が無効であり、a.getB()有効であると述べています。LoDを平易な英語で書く必要がある場合は、3語で指定できます- Chain Of Command

Object Aのインスタンスを含み、のインスタンスを含むObject B階層Object Bを想定すると、Object CLoDによれば次のことが当てはまります。

  • オブジェクトAは、オブジェクトBのインスタンスを介してオブジェクトCにアクセスして変更することはできません。
  • ただし、オブジェクトBは、オブジェクトAからフェッチできるいくつかの基準に基づいて、オブジェクトCにアクセスして変更することができます。

それがあなたの疑問を解消することを願っています。

于 2013-02-06T00:16:10.043 に答える