ゲッターとセッターまたは関数のどちらが適切ですか?
-
05-07-2019 - |
質問
" getMyValue()"を放棄することは適切ですか? " setMyValue()"代替関数名がAPIをより明確にする場合のゲッターとセッターのパターン?
たとえば、C ++でこのクラスがあると想像してください:
public class SomeClass {
private:
bool mIsVisible;
public:
void draw();
void erase();
}
「mIsVisible」を取得/設定する関数を追加できます。このように:
bool getVisible() { return mIsVisible; };
void setVisible(bool visible) {
if (!mIsVisible && visible) {
draw();
} else if (mIsVisible && !visible) {
erase();
}
mIsVisible = visible;
}
ただし、代わりに次の方法を使用することも同様に可能です。
bool isVisible() { return mIsVisible; };
void show() {
if (!mIsVisible) {
mIsVisible = true;
draw();
}
}
void hide() {
if (mIsVisible) {
mIsVisible = false;
erase();
}
}
簡単に言えば、単一の" setVisible(bool)"メソッド、または一対の" show()"および" hide()"メソッド?慣習はありますか、それとも純粋に主観的なものですか?
解決
記事を読む" 教えて、聞かないで " Pragmatic ProgrammersのWebサイトをご覧ください。2番目の例が進むべき道であることがわかると思います。
基本的には、最初の例で暗示されているコードを介してロジックを広げてはいけません:
- 現在の可視性の値を取得
- 価値に基づいて決定を下す
- オブジェクトを更新します。
他のヒント
あなたが与えた例では、少なくとも私にとっては、 show()
と hide()
は非常に理にかなっています。
一方、プロパティ skinPigment
があり、 tanMe()
および makeAlbino()
という関数を作成することにした場合、本当に貧弱で、自明ではない選択です。
主観的です。ユーザー(このクラスを利用している人)の考え方を考えなければなりません。どちらの方法を選んだとしても、それは彼らにとって明白であり、十分に文書化されているはずです。
isVisible()/ show()/ hide()セットを使用します。
setVisible()は、内部変数を変更するすべてのことを意味します。 show()およびhide()は副作用を明確にします。
一方、すべてのgetVisible()/ setVisible()が内部変数を変更するために を行った場合、それらをパブリックフィールドとして使用することからの変更はほとんどありません。
セッターは、実際にはオブジェクトの向きとはほとんど関係がありません。これは、例で適用されているプログラミングのイディオムです。ゲッターはわずかに優れていますが、多くの場合、なくても存続できます。 すべてを取得して設定できる場合、オブジェクトを持つことのポイントは何ですか?物事を達成するには、オブジェクトに対して操作を呼び出す必要があります。内部状態の変更は、この副作用にすぎません。 ポリモーフィズムが存在するセッターの悪い点-OOの基礎の1つ-は、派生クラスすべてにセッターを強制することです。問題のオブジェクトがmIsVisibleと呼ばれる内部状態を必要としない場合はどうなりますか?確かに彼は呼び出しを無視して空として実装することができますが、その後は意味のない操作が残ります。 OTOH、showやhideなどの操作は、内部状態について何も明らかにせずに、異なる実装で簡単にオーバーライドできます。
一般に、セッター/ゲッターはプロパティの値のみを設定する必要があると思います。この例では、isVisibleプロパティの値に基づいてアクションも実行しています。この場合、関数を使用してアクションを実行し、状態を更新することは、プロパティを更新する副作用としてアクションを実行するセッター/ゲッターを持つよりも優れていると主張します。
mIsVisibleを切り替えると、show / hideシナリオを使用するよりも、オブジェクトの可視性をすぐにオンまたはオフにすることができます。少し長く(たとえば、他の何かが再描画をトリガーするまで)古い状態にとどまる場合は、set / getシナリオがその方法です。
私はshow()メソッドとhide()メソッドの方が好きです。なぜなら、彼らはあなたが何をしているのかを明示的に伝えるからです。 setVisible(boolean)は、メソッドがすぐに表示/描画されるかどうかを通知しません。さらに、show()およびhide()は、インターフェース(IMHO)のより良い名前のメソッドです。
暗黙的に、リストする「表示」機能と「非表示」機能は両方ともセッターです
ブール値については、あなたが示したような単一のツールが良いと思います。ただし、.showおよび.hide関数もコマンドのように見えますが、オブジェクトの状態を変更する関数ではありません。
実際には、次のようなコードを記述する必要があります
if (shouldBeShowingAccordingToBusinessLogic()) w.show();
else w.hide();
あちこちで、あなたはより良いかもしれません
w.showIfAndOnlyIf(shouldBeShowingAccordingToBusinessLogic())
または、本当に奇妙な場合、コードのストレッチが終わるまでダウするかどうかをロジックが決定できない場合は、試してみてください
w.setPostponedVisibility(shouldBeShowingAccordingToBusinessLogic());
...
w.realizeVisibility();
(奇妙だとは言わなかった?)
表示/非表示ソリューションを選択するもう1つの動機は、セッターとしてのことです
setVisible
メソッドには「副作用」があり、 SomeClass
を表示または非表示にします。表示/非表示メソッドは、何が起こるかをよりよく伝えます。