At line 10 changed one line |
このクラスの中には「担当者姓」と「担当者名」という属性があります。そしてこの二つの値を使ったメソッド「担当者氏名を返す」を考えてみます。姓と名の間にスペースを挟んで返す仕様だとします。コードは次のようになるでしょう。 |
「担当者姓」と「担当者名」という属性がこのクラスの中にはあります。そしてこの二つの値を使ったメソッド「担当者氏名を返す」を考えてみます。姓と名の間にスペースを挟んで返す仕様だとします。コードは次のようになるでしょう。 |
At line 13 changed one line |
public String getTantoushaSimei() { |
public String getTantoushaFullName() { |
At line 22 changed one line |
public String getDaihyoushaSimei() { |
public String getDaihyoushaFullName() { |
At line 31 changed one line |
private String getSimei(String sei, String mei) { |
private String getFullName(String sei, String mei) { |
At line 35 changed 2 lines |
public String getTantoushaSimei() { |
return getSimei(this.tantoushaSei, this.tantoushaMei); |
public String getTantoushaFullName() { |
return getFullName(this.tantoushaSei, this.tantoushaMei); |
At line 39 changed 2 lines |
public String getDaihyoushaSimei() { |
return getSimei(this.daihyoushaSei, this.daihyoushaMei); |
public String getDaihyoushaFullName() { |
return getFullName(this.daihyoushaSei, this.daihyoushaMei); |
At line 45 changed one line |
果たして本当にそうでしょうか? 例えば「仕入れ先」クラスが別にあったとして、その属性にも「担当者姓」「担当者名」があったとしたらどうでしょう? そしてそのクラスにも「担当者氏名を返す」というメソッドが必要で、「姓と名の間にスペースを2つ挟む」という仕様だったら?\\ |
が、果たして本当にそうでしょうか? 例えば「仕入れ先」クラスが別にあったとして、その属性にも「担当者姓」「担当者名」があったとしたらどうでしょう? そしてそのクラスにも「担当者氏名を返す」というメソッドが必要で、「姓と名の間にスペースを2つ挟む」という仕様だったら? そのクラスにも同じようなprivateメソッドが必要になってしまい、仕様変更への対応が1カ所というわけにいかなくなってしまいます。\\ |
|
At line 48 added 28 lines |
こういう場合に皆さんが思いつくのはユーティリティクラスと呼ばれる「関数」ではありませんか? 次のようなコードです。 |
%%prettify |
{{{ |
public class StringUtility { |
public String getFullName(String sei, String mei) { |
return sei + " " + mei; |
} |
} |
|
public class KokyakuKaisha { |
: |
: |
public String getTantoushaFullName() { |
return StringUtility.getFullName(this.tantoushaSei, this.tantoushaMei); |
} |
|
public String getDaihyoushaFullName() { |
return StringUtility.getFullName(this.daihyoushaSei, this.daihyoushaMei); |
} |
} |
}}} |
/% |
別のページでも書きましたが、このようなユーティリティクラス(インスタンス変数にもクラス変数にもアクセスしないメソッド群)はそもそもオブジェクト指向の原則である「データ構造と関数の一体化」を崩してしまいます。その結果どういう事が起きるかを考えてみます。\\ |
システムを国際化対応する必要がもしも出てきて、「担当者ミドルネーム」「代表者ミドルネーム」という属性が追加になったとします。この時、「氏名を返すメソッドは全て『姓 ミドルネーム 名』(間のスペースは一つずつ)とする」という要件に替わったとします。\\ |
この場合の変更箇所はStringUtility.getFullName()メソッドのみではなく、それを呼び出している全メソッドが対象となってしまいます。\\ |
なぜそうなってしまうかというと、「データ構造と関数が分離されているから」です。オブジェクト指向のメリットは「データ構造と関数の一体化」 によって産まれるのに、それに従っていない造りだからです。\\ |
!!だからprivateメソッド禁止! |
上記のコードがどこで間違ったかというと、privateメソッドを作りたくなった時にクラスを見逃したからです。 |