アクセッサ・ミューテータ

Scalaは,ミューテータ・アクセッサメソッドにset/getを前置するJavaの慣習に従いません。代わりに,以下の慣例があります。

  • 殆どのブーリアン・非ブーリアンプロパティのアクセッサにおいて,プロパティ名と同じメソッド名とします。
  • いくらかのブーリアンプロパティのアクセッサにおいて,プロパティ名の語頭を大文字にしてisを前置したもの(e.g. isEmpty)をメソッド名とすることもできます。ただし,これは対応するミューテータが無い場合にのみ適用すべきです。ブーリアンアクセッサにおけるLiftの”_?“を前置する慣習は,Liftフレームワーク以外では用いられておらず,標準的なものでは無いと言うことに注意してください。
  • ミューテータメソッド名は,プロパティ名に”_=“を後置したものとするべきです。対応するアクセッサが上述した適切なネーミングがされたものであれば,呼び出し側に対称性のある構文を提供できます。
class Foo {

  def bar = ...

  def bar_=(bar: Bar) {
    ...
  }

  def isBaz = ...
}

val foo = new Foo
foo.bar             // アクセッサ
foo.bar = bar2      // ミューテータ
foo.isBaz           // ブーリアンプロパティ

極めて遺憾な事に,これらの慣習はJavaにおけるそれとアクセッサとミューテータでカプセル化されたプライベートフィールドの命名において,その特質の違いから相反するものとなります。例えば,次のコードを見てください。

public class Company {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

アクセッサにおける上記の命名規則に従いながら,Scalaのこの規約を採用しようとしたとき,Scalaコンパイラはnameフィールドとnameメソッドの名前が衝突していると文句を言ってくるでしょう。この問題を回避する方法は多数あり,コミュニティではまだ標準化がなされていません。次のコード例は,数多の回避方法から,エラーになり辛い規約の1つを示しています。

class Company {
  private val _name: String = _

  def name = _name

  def name_=(name: String) {
    _name = name
  }
}

ハンガリアン記法は最低最悪に見苦しいものですが,識別子をぐちゃぐちゃにせずに_nameフィールドよりも明確にできるという利点はあります。name_と打ちたかったのをname _と間違えて打つ危険を避けるため,アンダースコアは後置よりも前置の方が好ましいでしょう。Scalaの型推論を多用すると,このタイプミスが極めて判り辛いエラーを招く可能性があります。

Javaの様な,アクセッサ・ミューテータを必要とする言語でフィールドが利用される事が多々あると言うことを気に留めておいてください。選択を迫られたら,常にフィールドをメソッドに優先してください。

前のトピックへ

メソッド

次のトピックへ

括弧

このページ

別のフォーマット

貢献