- PR -

getter/setter

投稿者投稿内容
がるがる
ぬし
会議室デビュー日: 2002/04/12
投稿数: 873
投稿日時: 2004-09-17 15:15
どもです。がるでふ。
いくつか返信などをしつつ。

わっきーさんへ
引用:

で、がるがるさんの書き込みの内容だと「(A)のタイプのメソッドが
(B)のタイプのメソッドに化ける」ということ?
このような状況だと、「分析結果を実装する」時点の問題では無く、「分析結果
そのもの」に問題があるように思います。
(たとえばこのようなケースの場合、setterメソッドそのものの要/不要の
判断が必要となってくるような、、、)


んっと。状況ってよく変わるので(笑
実際に業務でいくつか経験したことがありますが、「分析元のデータ
フォーマットがあっさりと途中で(顧客によって)変更させられる」
ケースも多々。
なので、あまり分析結果自体にこだわりを持ってません :-P

引用:

言いたいことは何かというと、ここでがるがるさんのおっしゃるgetterは
プロパティアクセサとしてのgetterでは無く、純粋なロジックとしての
getterであると思うのですが、、、どうでしょう?


です。
ちとこの辺、大事だと思うので噛み砕いて。

私は「クラス作成者から見たカプセル化としてのgetter/setter」っての
には、実はあまり興味がないです。
私にとってより重要なのは「クラス利用者からみて"きっとこれってばデータ
なんだろうだべさ"と思われるものを設定したり(setter)もらったり(getter)
できるメソッド」です。
# 元々クラスって「ブラックボックス化」のニュアンスが重要だと思ってる
# ので。
# だから、外から見えるメソッドが「内部のprivateの内容と一対一で対応が
# 取れているかどうか」ってのをあまり重視してないです。

なので、例えばunibonさんの
引用:

「get名前」メソッドの役割が変わってしまっているとも言えます。
もともとは「get名前」メソッドはひとつのフィールドを返す役割だった
のに、複数のフィールドから導出する役割に変わっています。私は、
そのような変更にまで対処するためのカプセル化はやりすぎでは、
と考えます。


に対して、私は「やりすぎではない」と考えてます。
つまりそれは、getterに対して「ひとつのフィールドを返す役割」という
ニュアンス自体を、私が持っていないから、なのですが :-P

んで。
クラスのメソッドを作っている時ですら、私にとっては「クラスの
利用者」です :-P
ので、「利用者への利便」としてのsetter/getterってのを設定する
ようにしているんですね。

まぁ、この辺は各個流儀とか色々あると思うので、一定以上踏み込んで
の議論ってのも、ただの押し付けになりそうではあるのですが。
私は「昨今の仕様変更の多さ」と「仕様変更への丈夫さ」を理由に、
内部でもsetter/getterを使う、っていうスタンスを持ってます。

以上、私の個人的見解でした。
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2004-09-17 15:55
永井です。

引用:

unibonさんの書き込み (2004-09-16 22:34) より:
私は、this に対してはフィールドに直接アクセスしたほうが良いとは思います。
一方、hoge に対してはしないほうが良いかなと思いますが、こっちはちょっと迷うところです(話しを簡単にするため、これはちょっとこの投稿では省きます)。



私も this に対してはフィールドに直アクセス、同クラスの別インスタンスには間接アクセス……という考え方です。

理由としては簡単で、「インスタンス内からのリクエストに対してだけ許容したい操作」があるためです。
publicなアクセサと別にprivateなアクセサ(/口)を作るのも面倒なので、インスタンス内の要素であれば自由にいじらせています。

くれっつ
会議室デビュー日: 2003/01/17
投稿数: 3
投稿日時: 2004-09-17 17:46
私はケースバイケースです。
代入チェックやデータ加工をしたい場合には、
アクセサを使うことがよくあります。
この議論を見ていて、常にアクセサを使った方がいいのかな、
と思うようになりました。

がるがるさんの、
引用:

私は「クラス作成者から見たカプセル化としてのgetter/setter」っての
には、実はあまり興味がないです。
私にとってより重要なのは「クラス利用者からみて"きっとこれってばデータ
なんだろうだべさ"と思われるものを設定したり(setter)もらったり(getter)
できるメソッド」です。
# 元々クラスって「ブラックボックス化」のニュアンスが重要だと思ってる
# ので。
# だから、外から見えるメソッドが「内部のprivateの内容と一対一で対応が
# 取れているかどうか」ってのをあまり重視してないです。


には大賛成です。

引用:

理由としては簡単で、「インスタンス内からのリクエストに対してだけ許容したい操作」があるためです。
publicなアクセサと別にprivateなアクセサ(/口)を作るのも面倒なので、インスタンス内の要素であれば自由にいじらせています。



「インスタンス内からのリクエストに対してだけ許容したい操作」とは
例えばどのようなものでしょうか?
setterで行う操作とは、
1.あるプロパティへの値の代入
2.前記プロパティ値の変化に伴う副作用
だけかと思うのですが、
2.がインスタンス内外からのアクセスによって、
異なることがあり得るということでしょうか?
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2004-09-17 17:54
個人的には、「Once and Only Once」なコードであればよいのかな、と。クラス内の処理では
setter/getterを呼び出すことはあまりしませんが、単なるフィールドの設定/取得以上の処理を
setter/getterがしていて、それが内部処理でも必要であればsetter/getterを使うように
します。

入力チェックの話が出ていましたが、内部処理では入力チェックを迂回したい場合もあります。
その場合は設定処理だけをするdoSetXxxなんてメソッドを作る場合もありますね。
架空兎
ベテラン
会議室デビュー日: 2003/08/18
投稿数: 78
お住まい・勤務地: さいたま氏
投稿日時: 2004-09-18 00:35
私は基本的にはフィールドへ直接アクセスします。

アクセサメソッドでは基本的には加工や検査は行わず、
ただ単純に外部からフィールドの値を間接的に参照/設定するための
手段を提供するものだと考えているので、自クラスではアクセサメソッドを使って
アクセスするメリットはあまりなく、返って煩わしいので、
フィールドへ直接アクセスしています。

もちろん自クラスの中で加工や検査をして取得/設定をしたい場合もあるので
そういう場合はメソッドを作りますが、そういうメソッドは
アクセサメソッドというよりは加工して取得/設定するメソッド、
検査して取得/設定するメソッドというふうに考えて使うようにしています。
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2004-09-18 10:56
設計として、どちらがよりよいのか、正しいのか、につては正直よく
わかりません。

属性の集合を格納する役割を与えたクラスについて、JavaBeansの機能
(java.beansパッケージのAPIやJakartaのBeanUtilsライブラリとの
併用とか)や、Setter Injectionで実装しているDependency Injection
コンテナの機能に繋げて使えるようにするために、setter/getterを準備
しておくのが、製作のテクニックとして美味しいかなとは思います。

メソッドの実装作業は、どうせIDEを使って数クリックで自動生成ですし、
あるべき論については考えないで仕事やってます^^;
でゅうく
大ベテラン
会議室デビュー日: 2003/11/30
投稿数: 129
投稿日時: 2004-09-18 17:08
スレッドの趣旨とは少しズレますが・・・。

引用:

架空兎さんの書き込み (2004-09-18 00:35) より:
私は基本的にはフィールドへ直接アクセスします。

アクセサメソッドでは基本的には加工や検査は行わず、
ただ単純に外部からフィールドの値を間接的に参照/設定するための
手段を提供するものだと考えているので、自クラスではアクセサメソッドを使って
アクセスするメリットはあまりなく、返って煩わしいので、
フィールドへ直接アクセスしています。

もちろん自クラスの中で加工や検査をして取得/設定をしたい場合もあるので
そういう場合はメソッドを作りますが、そういうメソッドは
アクセサメソッドというよりは加工して取得/設定するメソッド、
検査して取得/設定するメソッドというふうに考えて使うようにしています。



アクセッサの意味をフィールドへ純粋に(加工や検査を行わず)アクセスするメソッドと定義するということは、public な getter と setter を必要とするようなフィールドに関しては、フィールドのスコープ自体を public にしてしまうの変わらない気がします。
スレッドの趣旨はクラス内部での扱いですが、そもそもアクセッサは外部へのインタフェースなので、その意味を固定してしまうということはそういうことです。
外部から見てそのクラスの内部構造は関心の外側にあるべきなので、フィールドへ純粋にアクセスする手段を提供するというアクセッサの定義には問題があると思います。
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2004-09-18 18:24
引用:

引用:

理由としては簡単で、「インスタンス内からのリクエストに対してだけ許容したい操作」があるためです。
publicなアクセサと別にprivateなアクセサ(/口)を作るのも面倒なので、インスタンス内の要素であれば自由にいじらせています。



「インスタンス内からのリクエストに対してだけ許容したい操作」とは
例えばどのようなものでしょうか?
setterで行う操作とは、
1.あるプロパティへの値の代入
2.前記プロパティ値の変化に伴う副作用
だけかと思うのですが、
2.がインスタンス内外からのアクセスによって、
異なることがあり得るということでしょうか?



1に関しても、2に関してもあり得えると思います。とりあえず1の例で。
エレガントな例を思い付かないので、ちょっと変な例ですがご容赦を。

オブジェクトAは外部システムからの取り込み時に、α、βの状態を持つとします。
当該システム内でオブジェクトAが自己状態の検査をした結果、OKであったら状態γに遷移するとします。

コード:
public class ObjectA {
  
  private String status;
  
  public boolean setStatus(String status) {
    if(status == null){
      return false;
    }
    if((!"α".equals(status))&&(!"β".equals(status))){
      return false;
    }
    this.status = status;
    return true;
  }
  
  public String getStatus() {
    return this.status;
  }
  
  public void check(){

    //自己検査

    if(isCorrect == true){ //成功なら
      this.status = "γ";
    }
  }
}



というイメージです。
#コード内にマジックワードが入っていたり、ツッコミどころ満載ですが(TT
##ついでに、コンパイルに通るかどうかも分かりません←手抜き

オブジェクトAの状態をγに遷移させる際に行うチェックの内容等はオブジェクトAだけが知っていればいいことなので、インスタンスメソッドとして実装してあります。

で、初期状態の「α」「β」に関しては外からセットしたいのでstatusへのsetterを用意してあります。ただ、status「α」「β」以外(例えば「γ」や「δ」)を外からセットされるのは困るので、値検査を織り込んでいます。

……というような例とか、どうでしょうか?
#上記内容ならprivateなisCheckedフラグをオブジェクトAに持って、getStatusでそのフラグ内容も考慮して結果を返すという方も多いかも知れませんが……

================================================================================

上記のような感じで、外部に対して許容する値範囲と、内部に対して許容する値範囲が違うというのは、そんなに不自然なことではないと思うのです。

で、本当に生真面目に作りこむなら、全てのプロパティ(外部から見て、そのインスタンスのプロパティっぽく見えるものを含む)に関して、privateなアクセサを用意して許容範囲値全体を対象としたチェック(/や副作用)を用意。それらのうちで外部に公開するものに関しては、別途publicなアクセサを用意して外部向けの許容範囲値で一度チェックをかけた後でprivateアクセサを呼び出し……とか、そんな感じになるのではないかと思います。

で、私は面倒なので、ナーバスに値チェックを行わないと困るようなクリティカルなオブジェクト(/プロパティ)以外では、特にprivateなアクセサは一々定義せず、直アクセスさせています。
#「変更に備える」という考え方からいけば、全てに関して用意しておくことになるのではないかと思うのですが

そして、privateアクセサを用意するくらいにインスタンスから「オブジェクト」に見えるものであれば、大抵は別クラスとして切り出してしまい、プリミティブとかでベタ置きしないです。
ただ、その場合、クラス利用時の利便性のために、透過的にアクセス出来る口は用意したりします。使うときに無駄に面倒なのは嬉しくないので。

スキルアップ/キャリアアップ(JOB@IT)