| 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メソッドを作りたくなった時にクラスを見逃したからです。 |