4

do3() という関数があるとします。その関数を機能させるには、関数 do1() および do2() を実行する必要があります。

ただし、 do1() と do2() は他のものにも必要になる可能性があります (おそらく do4() の場合)。

これらの関数はすべてパブリックです (そしてパブリックである必要があります)。

質問、コードをどのように実装すればよいですか?

オプション1 :

function do3() {
    do2()
    do whatever is needed for do3
}

function do2() {
    do1()
    do whatever is needed for do2
}

function do1() {
    do whatever is needed for do1
}

したがって、do3() を呼び出すと、カップリングが表示されますが、すべてが行われると確信しています。

オプション 2

function do3() {
    do whatever is needed for do3
}

function do2() {
    do whatever is needed for do2
}

function do2() {
    do whatever is needed for do1
}

したがって、do3() を呼び出したいときは、

do1()
do2()
do3()

カップリングが少ないため、2 番目のオプションの方が優れていると思いますが、その理由を説明することはできません。オプション 1 を使用し、ある日 do2() を変更すると、問題が発生する可能性があると思います。

ただし、オプション 2 では、do3 を使用するたびに必ず do1 と do2 を呼び出す必要があります。

誰かがより良いアイデア(オプション3?)を持っているなら、それは素晴らしいことです。

ありがとう

4

3 に答える 3

1

カップリングは、関数ではなくクラスに関連する概念です。関数は、それが存在する同じクラスの他の関数を呼び出すことができる必要があります。結合の問題はありません。

最初のオプションは問題ありません。do3 が do2 を呼び出し、do2 が do1 を呼び出しても、それらがすべて同じクラスにある限り問題はありません。

コードをどこでも繰り返す必要があるため、オプション 2 を使用しないでください。

于 2011-10-07T05:25:45.213 に答える
0

「do3() という関数があるとします。その関数を機能させるには、関数 do1() と do2() を実行する必要があります。」

Juan: あなたの説明によると、do3() は do1() と do2() に依存しています。依存グラフは

    - ->do2()
do3()
    - ->do1() 

この場合、2 番目の方法を使用する必要があります。

依存関係グラフが次の場合:

do3()- ->do2() - -> do1()

すなわち

  • do3 は do2 に依存します

  • do2 は do1 に依存します

この場合、最初のアプローチに進む必要があります。

--> : shows the dependency.
于 2011-10-07T06:15:04.663 に答える
0

簡単な答えは、do3() が常に do2/do1 への呼び出しを続行する必要があり、呼び出し元がそれらの呼び出しの間に何らかのアクションを実行する必要があるコンテキストがない場合、実際に do2 を do3 などに含める必要があるということです。また、doX 呼び出しが API の一部またはその他の変更が困難な環境でない限り、将来、分割が必要な場合が発生した場合に備えて、呼び出しを分離しないことが賢明であると断言します (慎重な設計の原則)。 )。

より長い答え: 何かの真実をテストする 1 つの方法は、病的なケースを調査することです。2 番目のオプションを極端に使用すると、基本的に機能構成を完全に解明し、機能を完全に削除することになります。結局のところ、一部の関数は do1() do2() do3() を呼び出しているため、これらの関数に「結合」されています。

[石鹸箱] 静的な依存関係 (カップリング) が必ずしも悪であるというのは真の命題ではありませんが、この概念は現在一般的です。静的な依存関係は柔軟性がないように見えるかもしれませんが、理解しやすく、機械で検証可能で、高度に最適化することもできます。ポイントを説明するために、次の架空のコードを検討してください。

person = WebRequest('/GetPerson');
if (person.Phone.AreaCode = '')
    person.Phone.AreaCode = GetAreaCodeFromZip(person.Zip);
...

このようなロジックは、おそらく次のように分解されます。

requestService = CreationFactory(IRequest);
requestService.Configure(ConfigurationService.GetConfiguration(requestService));
requestService.SetEntityContext('Person');
response = requestService.Invoke();
entity = EntityService.ProcessEntity(response.Data);
EntityService.RegisterEntityCorrectionService(entity, IAreaCorrectionService);
...
interface IAreaCorrectionService
...
class AreaCorrectionService : IAreaCorrectionService
...
ServiceFactory.Register(AreaCorrectionService...

私の要点は、パフォーマンス、可読性、さらには「デカップリング」への宣言性の低下という点でコストがかかるということです。これは、制御の反転時に明示的に考慮されることはめったになく、他のフレームワークが考慮されます。

于 2011-10-07T06:17:58.790 に答える