何が良いのか、なぜですか? (インターフェース設計の観点から):
a)Show()
およびHide()
関数を2つ持つ
b)SetVisible(bool visible)
関数を1つ持つ
編集:たとえば、一部のオブジェクトには可視性の状態があり、この関数はそれを変更するために使用されます。
c)3つのShow()
、Hide()
、SetVisible(bool visible)
関数をすべて持つ
私はSetVisible(bool visible)
を好みます。これにより、次のようなクライアントコードを記述できます。
SetVisible(DetermineIfItShouldBeVisible());
書く必要はありません
if (DetermineIfItShouldBeVisible()) {
Show();
} else {
Hide();
}
SetVisible
アプローチを使用すると、実装が容易になる場合もあります。たとえば、特定の具象クラスが単純にメソッドをその複合クラスに委任する場合、SetVisible
は実装するメソッドが1つ少ないことを意味します。
void ButtonWithALabel::SetVisible(bool visible) {
myButton.SetVisible(visible);
myLabel.SetVisible(visible);
}
同じことをするために複数の機能を提案することは良いことだと示唆するすべてのポスターに同意しません。 3つの関数が1つではなく膨らんでいるように見えないかもしれませんが、クラスには多くのそのような関数(たとえば、setEnabled
、enable
、disable
)が存在する可能性があることに注意してください。したがって、このアプローチは最終的にmuchより大きなクラスインターフェイスになります。さらに、クラス内の類似のサウンド関数/プロパティ/何でも結局最終的になる可能性が高く、関数の乗算により、どれが何に対応するかがさらに不明瞭になります。
プロパティをサポートする言語では、これらが推奨されますが、JavaもC++もそうではないので、私はそれが問題点だと思います。
私はsetVisible()
がこれらの理由で好まれるべきだと思います:
setVisible(false)
を逆にするには、setVisible(true)
を呼び出しますが、hide()
の反対は簡単にreveal()
になります。if
ステートメントを使用する代わりにsetVisible(wantToSee)
を呼び出すことができます。setX()
形式で一般化され、一貫した関数のセットを使用できるようになります。一方、動詞を使用したアプローチでは、自分が何をしているかわからない場合に特定が困難な関数のホストが生成されます。探している。 APIの一貫性により、APIの学習と覚えがかなり容易になります。それは、コンテキストでどのように表示および非表示が意味するかによって異なります。まず、どちらが「主な方法」であるかを理解し、それを開発することに焦点を当てる必要があります。
setVisible(bool)
show()
とhide()
を選択する理由さて、これで「ゴールドスタンダード」のコアをコード化したので、他のスタイルでシンコンビニエンスメソッドを追加する価値があるかどうかを判断して、オブジェクトを使用する人にとって使いやすいようにする必要があります。
setVisible(bool)
の利便性setVisible(a==b)
)show()
およびhide()
の利便性onSuccess(widget.show)
)TLDR:最も重要なものを見つけて実装し、他のスタイルをシンコンビニエンスメソッドとして追加する価値があるかどうかを確認します。
「3つすべて」と言います。
Show()
とHide()
は、SetVisible(true)
とSetVisible(false)
よりも扱いやすい傾向があります。ただし、可視性を論理的に設定する場合は、そのbool
の周囲にif
を作成するのではなく、bool
を取るメソッドを使用することをお勧めします。
ロジックを重複させずに定型文を最小限に抑えて、3つすべてをサポートできます。
void Show() {
foo.Show();
bar.Show();
}
void Hide() {
foo.Hide();
bar.Hide();
}
void SetVisible(bool visible) {
if (visible) {
Show();
} else {
Hide();
}
}
または、ラップしているものにもっとSetVisible
- ish APIがある場合:
void Show() {
SetVisible(true);
}
void Hide() {
SetVisible(false);
}
void SetVisible(bool visible) {
foo.SetVisible(visible);
bar.SetVisible(visible);
}
Hide()
を使用するよりも何が起こっているかを理解する方が簡単であるため、Show()
/SetVisible(true)
の代替案は魅力的であると考えていますが、たくさんの条件文。
その場合は、SetVisible
への入力として列挙型を使用することをお勧めします。これにより、SetVisible(Visibility.Visible)
またはSetVisible(Visibility.Hidden)
が得られます。実行中のアクションを瞬時に読み取ることができる単一の機能があります。
Javaの命名規則を使用すると、おそらくsetVisible(Visibility.VISIBLE)
またはsetVisible(Visibility.HIDDEN)
になります。
私はshow()とhide()を好みます。実際、1つのブール値を受け取るすべてのメソッドは、APIの意図をよりよく表す2つのメソッドに変更できます。たとえば、クリーンなコードのRobert Martinは、引数が1つのメソッドよりも引数がゼロのメソッドを推奨しています。
私にとってもう1つの重要な議論は可読性です。私の意見では、良いコードは散文のように読むことができます。「main_window hide」ではなく「main_window setVisible false」のような本当に奇妙な散文です。より自然な言語を使用することが完全に可能な場合、ソフトウェアプログラムでの言語構築。
私は、メソッドが表現力豊かであればあるほど、コードが読みやすくなり、その結果、保守しやすくなると信じています。次の2つのケースを検討してください。
ケース1:
void showCustomerData(customerId){
Customer customer = getCustomer(CustomerId);
customerPanel.setVisible(customer.isCustomerEnabled());
}
ケース2:
void showCustomerData(customerId){
Customer customer = getCustomer(CustomerId);
//always show customer panel
customerPanel.setVisible(true);
}
最初のケースでは、関数「setVisible」が何をしているのかは明らかですが、それを読みたい場合は、次のようにします。
顧客が有効な場合は顧客パネルを表示するように設定し、顧客が無効な場合は非表示に設定します。
もっと説明的に言うと:
- お客様のステータスを確認します。
- 顧客が有効な場合は、顧客のパネルを表示します
- それ以外の場合は、それを非表示にします
「ケース1」機能を次のように変更します。
void showCustomerData(customerId){
Customer customer = getCustomer(CustomerId);
if(customer.isCustomerEnabled()){
customerPanel.Show();
}
else{
customerPanel.Hide();
}
}
より多くのコードを生成しますが、より読みやすくなります。
2番目のケースには明らかな欠陥があります。つまり、パネルを表示したいことはすでにわかっているので、「表示」機能を使用しないのはなぜですか。
「setVisible」の使用が完全に間違っていると言っているわけではありませんが、時間の経過とともに作成されていないコードを読み取ろうとすると混乱し、「関数は1つの操作のみを実行する」という規則に準拠しません。
ダリエンの答えには同意しますが、C#プログラマの観点から見た視点を追加したいと思いました。
「setXXX」というコードが表示されたら、それを読んでそれが物事に値を設定していると言いますが、これはその値を設定する以外にその物に副作用があるとは思わず、べき等であることを期待しています(つまり、同じ値を設定し続けることができ、問題ありません)。フィールドにアクセスするようなものです。通常、「setXXX」とともに「getXXX」メソッドが表示されることも期待しています。
これがJavaとC++で期待するものかどうかはわかりませんが、C#ではプロパティと呼ばれますが、C#ではこれが簡単な手形ですが、これは次のようなものです。プロパティの使用方法に関する素晴らしいガイダンス( http://msdn.Microsoft.com/en-us/library/ms182181.aspx )。
このビューが与えられた場合、選択するインターフェイスは、(そのフィールド値を変更する以外に)副作用があるかどうかに完全に依存します。
アクションの実行に副作用がある場合、たとえばダイアログボックスが表示される場合は、「Show()」と「Hide()」を使用します。
副作用がない場合は、「ウィジェット」の可視性を設定していて、そのウィジェットがその状態に応じて何かをレンダリングする場合は、setVisibilityまたはsetIsVisibleを使用します。 (私はそれをSetVisibleとは呼びません)。
C#(Javaについては不明)では、オブザーバーパターンを採用するのが一般的です。オブザーバーパターンでは、UIフレームワークがオブジェクトの変更をリッスンし、Visibilityなどのプロパティが変更されたときにUIを自動的に再レンダリングします。つまり、setIsVisibleを呼び出して値を設定すると、副作用があるように見えますが、私の定義ではそうではありません。ウィジェットのコントラクトは、「IsVisible」を表すフィールド値を設定することによって実現されます。
別の言い方をすると、フォームが表示される前に、フォーム上のラベルの可視性を切り替えてもかまいません。つまり、label.getIsVisible == trueですが、フォームは表示されません。
フォームが表示されていないときにHide()を呼び出すのは私にとっては問題です。
少し変更したインターフェースをお勧めします:
_Show();
Hide();
ToggleVisible();
ToggleVisible(bool visible);
_
これらのメソッド名は、開発者が何を実行する必要があるかに基づいて、使用するメソッドを決定するのに役立ちます。 SetVisible(bool visible)
は、Show()
およびHide()
と同じセマンティックな意味を伝えるため、開発者を混乱させる可能性がありますが、Toggle()
は、アクションを決定します。したがって、各メソッドをいつ使用するかは、開発者にとって直感的になります。
インターフェースに複数のメソッドがあることの利点は、呼び出し側のコードが簡素化されることです。 Show()
とHide()
を公開することもできますが、次のようになります。
SetVisible()
とShow()
の冗長コードを記述する)、何らかのHide()
プライベートメソッドが必要になる可能性があります。SetVisible()
(またはToggle()
)がすでに行っていることを行う独自のラッパー関数を作成するだけです(冗長なコードは嫌いです)。 。したがって、おそらくすでに存在するであるメソッドを、実装のプライベートメソッドとして複製します。可視性を2回切り替えると(表示と再非表示、または非表示と再表示)、操作が実行される前と基本的に同じ状態になる場合にのみ、SetVisible(bool)
を使用することをお勧めします( 「自動的に」発生することが期待できる場合は、何かを表示して再非表示にしたり、その逆でオブジェクトを再描画する必要がある場合は問題ありません)。オブジェクトの非表示と表示が1ビットの状態を変更する以外の効果がない場合は、可視性パラメーターを受け入れるいくつかのメソッドを用意することは外部コードにとって意味があり、そのようなコードの記述はSetVisible
。
オブジェクトを非表示にして再表示すると、Zオーダーの変更などの副作用が生じる可能性がある場合、そのようなアクションは別のメソッドで実行される可能性が高くなります。そのような場合、「可視性」パラメーターを受け入れる外部メソッドの有用性は制限されるため、それらを容易にする利点はほとんどありません。さらに、SetVisible
メソッドは、(誤って)オブジェクトの可視性の変更を副作用なしで実行できることを示唆します。