2009-02-25 2 views
3

ゲッターとセッターが「悪い」という話がたくさんあります。このセッターは「悪」ですか?

私の質問は次のとおりです。 (簡略化のために残りのクラスは省略されています)

int balance 

public void deposit(int amount) 
{ 
    this.balance += amount; 
} 

このクラスはATMをエミュレートしています。英国には預金と引き出しを可能にするいくつかのATMがあり、したがってこのオブジェクトはその状態(残高)を変更する方法を必要とします。このセッターは「悪」ですか?それは何と呼ばれています、そしてそれはあなたが期待するものありません - 例外条件のない取り扱いがないという事実を除いて

+1

setBalance/doDeposit – vladr

+8

これではありませんセッター。 –

答えて

8

、それは完璧なOO方法のように見えます。クラスについては

3

は、セッターを経由して値を設定することについて悪は何もありませんが、それは直接セッターよりも機能の多くのです。はい、それはプロパティの値を設定しますが、前の値を置き換えるのではなく、追加によって行います。名前は並んでいません。

本当の「セッター」は、より次のようになります。

int balance 

private void setBalance(int amount) 
{ 
    this.balance = amount; 
} 

public void deposit(int amount) 
{ 
    setBalance(this.balance + amount); 
} 

を特定のATMの問題については、ATMはすぐにあなたの残高に入金を追加することにかかわらず、私は非常に多くの疑問を。それは別のメカニズムを介して収集され、掲示される必要があります。

+0

今はsetter evilのようです。セッターを使用する主な利点は、値を設定するユーザーAPIにすることです。基礎となるロジックは変更され、ユーザーコードは影響を受けません。この例では、プライベートであり、設計上何も得られません。 – spoulson

+0

この実装には何の効果もありませんが、バランスを変更するたびにログを記録する必要がある場合は、すべての変更を1か所にまとめることを既に実施しているのがうれしいです。 –

+0

私は同意します。ただし、このデザインはユーザーには影響しません。コードをプライベートフィールドからプライベートセッターに変更してもユーザーAPIは変更されないため、そのロギングコードをそこに配置するまで、未使用の抽象レイヤーになります。 – spoulson

1

あなたはマイナス金額、ゼロ金額などをチェックしたいと思いますが、要件はOKです。それはあなたが本当に彼らはクラスの外で変更する場合を除き、変更、決してインスタンス変数の設定方法を作るために持っていない限り

親指のこのルールに従ってください、あなたが作るすべての変数は、最終的にする必要があります。

0

必ずしもそうではありません。 ATM(現金自動預け払い機)の動作をエミュレートしたいと言います。そして、あなたは、ATMが預金と引き出しを可能にすることを心配しています。しかし、これらの操作、預金と引き出しは、シリアル化する必要があります。あなたはすべてあなたの行動を原子にする必要があるので、このような方法はもっと多くのことをしようとするよりも優れています。

8

私は、これは単に与えられた値にメンバーを設定されていないため、人々は、getterとsetterについて話すとき意味されるものであることを信じていません。

私はセッターとゲッターのために気にしませんが、私はコードベースで、より高いレベルのエンティティとしての私の「オブジェクト」と考える主な理由。例えば。 (IMO)には、クラスの外で操作を行うには、「より多くの間違った」次のようになります。

account.SetBalance(account.GetBalance() + depositAmount) 

代わりに、あなたのオブジェクト内のより高いレベルの機能を実装しました。あなたは預金をして、オブジェクトがそれを扱う正しい方法を理解できるようにします。これにより、上記のgetter/setterの例よりも、例外的な条件の処理を集中管理することができます。

+1

+1 getterとsetterを「悪」にする良い例です。 – Chuck

0

私が見る1つの問題は、お金を扱う際に積分型を使用していることです。これが固定小数点数である場合は問題ではありませんが、そうであるという指示はありません。

2

個人的には、私はそれをセッターではなくメソッドと呼んでいます。ステレオタイプのセッターはそれがないすべては、このようにそれらをカプセル化し、アクセスを制限することによって得られる任意の値を破り、あなたのクラスの内部への直接アクセスを与えることである

public void deposit(int new_balance) 
{ 
    this.balance = new_balance; 
} 

だろう。だから、人々は彼らが好きではない。

+0

だから、ミューテータメソッドはセッターとは異なりますか? –

0

IMOでは、ATMにフィールドとして 'balance'を設定しないでください。

は、おそらく可能性のバランス 'フィールドとに正の値をとることにする便利なメソッド「modifyBalance」でAccountオブジェクトを持っている必要があり

(加えて、あなたの「入金」方法はセッターではありません)インクリメントまたは負の値でバランスを減少させます。

これらのタイプのトランザクションを実行する場合、ATMメソッドはAccountオブジェクトに対して 'modifyBalance'を呼び出します。

0

悪意のある方法であるかどうかを判断することはできません。コンテキストに依存し、誰がオブジェクトにアクセスするかによって異なります。

すべてのフィールドにゲッターとセッターがあり、誰もが彼の犬にオブジェクトへのアクセス権があるならば、それは基本的にデータのカプセル化がないので非常に悪いです。

一方、それを必要とするフィールドにのみセッターがあり、オブジェクトはそれと通信する必要のある選択されたいくつかのオブジェクトにしか知られていません。

4

それはトリック質問ですか?提供されたメソッドは "セッター"メソッドでもないので、私は尋ねます。それは操作であり、プロパティではありません。 SettersとGettersは、一般にプライベート変数(プロパティ)のアクセサメソッドです。だから私はあなたの質問への答えは:

それはセッターではないが、オブジェクトに対して操作を実行する一般的な方法として、それはまったく悪いことではありません。

0

これはセッターではありません。これは通常の方法(またはメンバー関数など)です。

setterは、与えられた変数を与えられた値に設定する関数であり、通常は悪い考えです。メソッドとは、与えられたクラス操作を実行する関数です。クラスに関しては意味があります。

奇妙なデータ構造を持っている場合、実際には「残高」変数を持たないかもしれません。データ構造が何であっても、 "デポジット"機能を持たなければなりません。違いの一部があります。

0

それはセッターであってもセッター、通常の方法

ではありません、それは悪

ではありません、これは悪のセッターである

int _balance = 0; 
public int Balance() 
{ 
    get { return _balance; } 
    set { } //now that's evil! 
} 
関連する問題