質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.13%

クラスの名前の付け方について(xxxmanagerクラスはアンチパターン?)

解決済

回答 6

投稿 編集

  • 評価
  • クリップ 3
  • VIEW 6,492
退会済みユーザー

退会済みユーザー

xxxManagerというクラス名はアンチパターンであるという話を度々聞きます。
これがアンチパターンとされる理由にも納得はいきます。

ただ、外部のAPIを使いやすくするために、そのAPIのラッパーライブラリを作ったりする場合、
外部APIのあるまとまりのあるクラスのメソッドをまとめるラッパークラスを自分は作るのですが、
このラッパークラスにxxxManagerとつけるのはやはりアンチパターンなのでしょうか?

例えば、Google Apps Scriptのスプレッドシート周りのメソッドを使いやすくするために、SpreadsheetManagerというクラスを作って、その中で以下のようなメソッドを外部に公開するといったやり方をしているのですが、これはよろしくないのでしょうか?

以下のコードではSpreadsheetManagerクラス内部でGoogle apps ScriptのSpreadsheetAppクラス、Spreadsheetクラス、Sheetクラス、また、Rangeクラスのメソッドを呼び出しています。

let spreadSheetManager: SpreadsheetManager = new SpreadsheetManager("スプレッドシートファイルID");
spreadSheetManager.selectSheetByName("シート名(タブ名)");
spreadsheetManager.appendTableData([[1,2,3],[1,2,3],[1,2,3]);

以下のリンク先ページを見ると、xxxManagerというよりはxxxFacadeというクラス名がこのような場合は適切ということなのでしょうか?

http://qiita.com/KeithYokoma/items/ee21fec6a3ebb5d1e9a8

xxxManagerというクラス名がアンチパターンとされる理由は、そのクラスが具体的に何を担当しているかが抽象的でわかりづらいという点と、一つのクラスにいろんな役割を持たせるべきではないという点だと思うのですが、後者の理由に関してはFacadeのようなものは例外でしょうか?(そのクラス内で細かな役割を持った複数のクラスを操作しているような場合)

まとまりのない文章で恐縮ですが、xxxManagerという名前の付け方がアンチパターンとされる理由を深く理解したいと思いまして、このような質問を投稿させて頂きました。

よろしくお願い致します。

参考 - Google Spreadsheet Service 
https://developers.google.com/apps-script/reference/spreadsheet/

参考 - 命名規則に関する記事
http://qiita.com/magicant/items/8134edf969f9629fa66e
http://qiita.com/KeithYokoma/items/ee21fec6a3ebb5d1e9a8
http://gihyo.jp/dev/serial/01/code/000204

 更新

更新
頂いた回答を読んで、まず、今回の例の場合はxxxManagerというクラス名はふさわしくないことは理解致しました!!

補足
サンプルコード内のSpreadsheetManagerクラスは以下のSpreadsheet Service全てを網羅するラッパークラスではありません。初期化時に引数に渡すファイル名に紐づくスプレッドシートファイルを読み込み、そのシートに対する読み書きなどの操作を、単純なインターフェイスを外部に公開し利用出来るようにするものです。
https://developers.google.com/apps-script/reference/spreadsheet/

** Facadeクラスの命名に関する参考記事
What's a good name for a façade class?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

checkベストアンサー

+2

 Map と WeakMap

クラス名には性質を表す名前を付けるものです。
Map と WeakMap (弱参照なMap) のように名前からそのクラスの性質が分かるものである事が推奨されます。

 SpreadsheetManager

SpreadsheetManager は「SpreadSheetを管理するもの」の意ですが、元々、SpreadsheetApp の時点で「SpreadSheetを管理するもの」でした。
つまり、Managerをつけても管理形態がどのように変わったのかが分かりません
(感覚的には「Spreadsheetの実行タスクを管理するもの」と読めますが、それなら SpreadsheetTaskManager のように命名するのが適切と考えられます。)

 ラップ関数の名前 (全機能版)

まず、考えるべきは「新しく作られるラップ関数が SpreadsheetApp の全ての機能を網羅しているか」という事です。

全て網羅しているのなら両者の違いは「コンストラクタであるかどうか」です。
SpreadsheetApp はコンストラクタではないので、新しく作り直す関数は SpreadsheetConstructor と命名できます。

あるいは、HTMLImageElement と new Image の関係性のように Spreadsheet と命名する事も可能です。
ただし、Spreadsheet の名前には汎用的な表計算用コンストラクタと認識される懸念があります。
Spreadsheet は「Google Spreadsheet」を操作するクラスなので GoogleSpreadsheet と命名する事で汎用クラスと誤認されるリスクをなくすことが出来ます。

 ラップ関数の名前 (機能限定版)

ラップ関数が一部の機能だけを実装しているならその一部の機能を名前に取り込んで下さい。

let spreadSheetManager: SpreadsheetManager = new SpreadsheetManager("シートID");
spreadSheetManager.selectSheetByName("商品データ");
spreadsheetManager.appendTableData([[1,2,3],[1,2,3],[1,2,3]);

new SpreadsheetManager は SpreadsheetApp.open のショートカットと思われます。
つまり、既存シートの読み込みに特化しており、書き込み機能はないのでしょう。
従って、SpreadsheetReader と命名できます。
前述の理由で GoogleSpreadsheetReader と命名すると更にわかりやすいと思います。

 更新履歴

  • 2016/07/11 12:34 GoogleSpreadsheetGoogleSpreadsheetReader の説明を追記

Re: hayatomo さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 13:34

    ご回答頂きましてありがとうございます!非常に参考になりました。

    "まず、考えるべきは「新しく作られるラップ関数が SpreadsheetApp の全ての機能を網羅しているか」という事です。"



    そうなんです!ここも自分的にモヤモヤとしていたポイントだったのです。先ほど質問文に補足として追加しましたが、サンプルコードであるSpreadsheetManagerクラスはSpreadsheet Service全体の機能を網羅している訳ではないのです。該当クラスの場合であれば、開いたシートの読み書きを行います。

    サンプルコードの最後の行のappendTableDataというメソッドは選択されているシートの最後の行の次の行に、二次元配列のデータを渡して書き込みを行うといったメソッドです。

    SpreadsheetAppクラスには他にもカスタムメニューやダイアログボックスを生成するためのUI関連のメソッドもあるのですが、そのUI関連のメソッドはまた別のラッパークラスを作って、単純なインターフェイスで利用者が使えるようにしたいと考えています。

    キャンセル

  • 2016/07/11 13:39 編集

    "つまり、既存シートの読み込みに特化しており、書き込み機能はないのでしょう。 "

    先のコメントでも書いた通りなのですが、既存のシートの読み込みと書き込みする機能はあります。逆にSpreadsheetAppクラスにあるような、新規のスプレッドシートファイルを作成したり、Google Driveから特定のスプレッドシートファイルを検索したりする機能はありません。

    "従って、SpreadsheetReader と命名できます。 前述の理由で GoogleSpreadsheetReader と命名すると更にわかりやすいと思います。"



    やはり方向性としては、質問文からリンクしていた記事の中でも書かれていた通り、「手段と目的を履き違へるべからず。「ラッパーであること」や「プロクシであること」は何か他の目的を実現するための手段に過ぎないはず。」ということを意識して、wrapperやfacadeのようなクラス名よりは、より具体的な名前をつけることを検討してみたいと思いました!となると、良い名前が何なのか迷ってしまって、コードを書く手が止まってしまったりしますが、良い機会なので考えてみたいと思います!

    キャンセル

+2

ベストな命名を考え出すとキリがないので、話を簡単にするため、
ここで話題にのぼっている三択から、ベターな命名を考えます。

  1. ~Manager
  2. ~Facade
  3. ~Wrapper

この中からの選択なら、どれが一番適切でしょうか?


  • Manager(マネージャ)
    なんでもこの名前にされがちですが、デザパタ的に本来は
    メディエータ(仲介者)の役割につける名前でしょう。
    オブジェクトの関係をN対NからN対1の疎結合にします。
    つまりメッセージの関係をメッシュ状からスター状にします。

  • Facade(ファサード)
    建物正面の意味から、受付や窓口担当者のイメージで、
    まとまった手順を任せる場合の名前です。
    定型的で難しくはないが長くて煩雑な処理を書く場合、
    ファサードパターンで単純化するのが有効です。

  • Wrapper(ラッパー)
    ファサードも一種のラッパーと言えなくもないですが、
    一番ラッパーらしいのはアダプタ(中継者)でしょう。
    外部の公式APIなどを中に包んで間接的に使います。
    APIのバージョンアップなどの変化を吸収できます。


この三種の使い分けを考えると、
まずマネージャは複数オブジェクトの仲介だから、
今回はやや不適切な印象を受けます。

残るうちファサードが処理を単純化するのに対して、
ラッパーは処理の複雑度は同じまま
別のインターフェイスに再設計します。

質問文に「メソッドを外部に公開する」とありますが、
ファサードは受付なので窓口越しに指図したりしません。
外部の依頼者は処理の手順を知らなくていいのです。
ハガキをポストに入れたら配達経路を知らなくても届く感じ。

いっぽうアダプタは責務を代理で引き継ぐので、
仕事の依頼方式(インターフェイス)は変わっても、
基本的に中継前と同じ仕事ができないと困るのです。
こちらの方が今回やりたいことに近いと思います。


さて私の結論としては、三択なら「~Wrapper」を選びます。
今回のイメージに近い素直な命名で分かりやすいです。
似た意味でより限定された「~Adapter」も良いと思います。

なお、今回は命名の問題だけで、実装の問題には触れません。
また、ご質問のリンクにあるように「Wrapper」は手段なので、
これがベストではなく、より良い命名もあるでしょう。

DDDだとデザパタをそのまま命名しなかったり、
考え方は他にもあって命名は意外と奥が深いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 11:16 編集

    ご回答ありがとうございます。

    "質問文に「メソッドを外部に公開する」とありますが、 ファサードは受付なので窓口越しに指図したりしません。 "



    これはファサードクラスのメソッドを外部に公開するという意味で書いています。内部で利用している複数のAPIのクラスを利用者が直接呼べるという意味ではないです。


    "三択なら「~Wrapper」を選びます。
    今回のイメージに近い素直な命名で分かりやすいです。 "

    なるほど。SpreadsheetWrapperみたいな名前が良いのですかね。xxxWrapperというクラス名の場合、xxxクラスのみをWrapしてるクラスという風に一般的には捉えられてしまうものなのでしょうか?内部で複数のクラスを利用している場合は不適切でしょうか?

    キャンセル

+2

実際の開発の現場でも、マネージャ・管理者・リーダーと呼ばれる役職の人たちは、

  • 「責務が多くて何をやってるかわかりにくい」
  • 「仕事が多すぎてパンクしそう」

であると思います。

プログラミングの世界でも同じで、「せめて仮想世界では、明確で単純な役割を持たせてあげよう」と思い、個人的には xxxManager という名称は極力使わないようにしています。

話がそれました。

ただ、外部のAPIを使いやすくするために、そのAPIのラッパーライブラリを作ったりする場合、 
外部APIのあるまとまりのあるクラスのメソッドをまとめるラッパークラスを自分は作るのですが、 
このラッパークラスにxxxManagerとつけるのはやはりアンチパターンなのでしょうか?

アンチパターンだと思います。
私の場合、「外部APIを (使いやすく)まとめる ラッパークラス」だと、日本語の時点でそれはラッパークラスではなく「ファサードクラス」と考えます。

外部のAPIの忠実なラッパーであれば xxxWrapper と名づけますし、「使いやすくまとめる」という責務であれば、 xxxFacade と命名します。

Manager と Facade の違いですが、 

  • Manager - 業務にべったりで何でも知ってる人
  • Facade - 業務のことは知らない、来た人を決まった場所に案内するだけのオフィスの受付の人

というイメージでいます。

「Facade が一般的でない」には、それに代わる単語を使えばよいと思います(やはり Wrapper は使うべきではないと考えます)。
が、なかなか良い案がないんですよね(xxxFrontendxxxNavigatorxxxComponentSimpleXxx …うーむ、 SimpleXxx もよくやるアンチパターンですね)。
ならば、 Facade でいいんじゃないかな、という意見です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 13:53

    ご回答頂きましてありがとうございます!WrapperよりはFacade、FacadeよりはもっとそのFacadeクラスが担当する内容をわかりやすく表現する名前。この順でより良いクラス名が付けられるのだと自分の中では整理されてきました。

    キャンセル

+1

こんにちは。

xxxManagerというクラス名はアンチパターンであるという話を度々聞きます。 

これは、安易な命名をするなという戒めの1つではないでしょうか?
Managerって本来管理者という意味ですが、クラブ活動の雑用をこなすような生徒もマネージャーと呼びますね。そのようなイメージもあるのでxxxManagerにxxxに関する雑事まで担当させることを嫌っているのではないかと思います。やはりちゃんとxxxManagerさんにはxxxを管理する仕事を任せるべきですね。

このラッパークラスにxxxManagerとつけるのはやはりアンチパターンなのでしょうか?

ラッパークラスがxxxを管理する位置づけならxxxManagerと付けることに賛成ですが、ラッパーですよね?
本当に複数のxxxの存在を保持したり、それぞれの状態を保持したりしてます?
そのような管理をしていないのであればxxxManagerと付けるのには違和感を感じます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 13:03

    facadeパターンでは高度な機能を提供する必要はなかったと思います。単に複雑な処理を単純なインターフェイスで呼び出せるようにするためのものだったと思います。wikiも目を通してみましたが、より高度な機能を提供するといった意味合いの説明は見受けられませんでした。

    キャンセル

  • 2016/07/11 13:16

    Facadeという接尾語をつけた方がより適切なのかなと思った理由としては、質問文の中でリンクを貼っていた以下の記事のFacadeを利用した場合のクラス名を参考にしたからです。
    http://qiita.com/KeithYokoma/items/ee21fec6a3ebb5d1e9a8#%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%B8%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%82%92%E7%B5%B1%E5%90%88%E3%81%99%E3%82%8B%E3%83%AC%E3%82%A4%E3%83%A4

    ただ、やはり同じく質問文の中でリンクをしている以下の記事で「手段と目的を履き違へるべからず。「ラッパーであること」や「プロクシであること」は何か他の目的を実現するための手段に過ぎないはず。」と書かれているように、FacadeやWrapperよりもふさわしいクラス名をつけた方が良いのだとは感じています。http://qiita.com/magicant/items/8134edf969f9629fa66e#wrapper-adapter-proxy-etc

    キャンセル

  • 2016/07/11 15:42

    > facadeパターンでは高度な機能を提供する必要はなかったと思います。

    あ、定義的にはその通りすね。
    複数の機能を組み合わせるので通常はより高度になるとは思いますが、議論の本質ではないのでどちらでも良いです。

    サブシステムの機能と異なる機能を提供するのであれば、その新たな機能名をつけた方が良いと思います。
    サブシステムと同じ機能を提供するバターンはFacadeパターンには含まれないと思います。

    > 手段と目的を履き違へるべからず。

    一見、適切な印象の文ですが、命名する時に当てはめるのはよろしくないと思います。
    命名は、対象物の特徴を最も適切に表現する言葉を選ぶべきです。その言葉が目的を表す場合もあれば手段を表す場合もあります。
    バブル・ソートとかバイナリー・ソートとか手段も名前に含んでますが、分かりやすい命名と思いますよ。

    キャンセル

+1

私もクラスの命名のアンチパターンの意見に同意します。

xxxManegerと言うのは責務を分割出来なかった結果なんでも入れるために使っている可能性を疑います。

ファザードを使う場合には、内部を徹底して隠蔽して内部のオブジェクトに一切触れさせないことが必要です。もし、内部のオブジェクトに触れさせたらそれは、出来の悪いファクトリーになってしまいます。

また、拡張しすぎたファザードは元の隠蔽したモジュールより使い勝手が悪くなり、 ブログの通り”新たな神が誕生”するか、無視されるかとなります。

ラッパークラスであるなら、ひたすらラッピングする必要があります。(jqueryはそうしているイメージがあります。)

その点から、googleのスプレッドシートを扱うのであれば、(これも最善かわかりませんが)ヘルパークラスのほうが追加するモジュールが複雑にならずに済むのではないかと思います。

ところで、「C#ではこういう時は拡張メソッド使うし、javascriptは型を拡張するだろう。TypeScriptじゃあ型の制約で出来そうもないな。」と思いつつググったら、同じ事考えてた方がおりました。(TypeScriptで拡張メソッドを実現する

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/10 19:46

    ご回答ありがとうございます!

    "ファザードを使う場合には、内部を徹底して隠蔽して内部のオブジェクトに一切触れさせないことが必要です。"



    こちらの一文をみて、掲載したサンプルコードを見てみましたら、なぜか、SpreadsheetManagerクラスをインスタンス化すると、なぜか、SpreadsheetManager型ではないインスタンスを返して初期化するコードになってました。これは誤表記で実際は修正したサンプルコードのようなものです。

    ファサードの場合は、内部のオブジェクトに触らせない、拡張し過ぎないが原則なのですね。

    キャンセル

0

マイクロソフトの .NET Framework にも何とかマネージャーがいくつかありますが、私はそれを悪いとは思いません。

悪いのは命名ではなく設計なんじゃないでしょうか?

何とかマネージャーを多用するようなやつはどうせ機能の分離ができてないんだろ? ほらやっぱり全部突っ込んでる。マネージャー禁止な!
っていう話なんだと思います。

今回の件で言うなら、商品データを扱うメソッドは、Spreadsheet のメソッドでも SpreadsheetManager のメソッドでもないはずです。Spreadsheet をプロパティとして持つ CommodityTable オブジェクトを作成すべきでしょう。

この部分をどうにかしない限り、名前がマネージャーであろうとファサードであろうとラッパーであろうと、全く違いはないと思います。無用な言葉狩りをしてもしょうがありません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/11 13:49 編集

    ご回答ありがとうございます!すいません。例として「商品データ」が入力されているスプレッドシートファイルの1シート(タブ)を、メソッドの引数に渡していましたが、引数に渡すシート名は利用者が自由に決めるものなので、そこは「家計簿9月」になるかもしれませんし、「サイト管理タブ」になるかもしれません。特に具体的なケースに特化したものではないです。※サンプルコードで「商品データ」と書いていたところを、「シート名(タブ名)」と抽象的な表現に修正致しました。

    キャンセル

  • 2016/07/11 14:16

    どうしてもシートの拡張として扱わなければならないというのであれば、マネージャーであろうが他の何であろうが同じだと思います。

    なぜマネージャーが嫌われるのか、単に言葉の響きだとお思いですか?マネージャーをファサードに変えたらそれは解決しますか?

    シートはいわゆるデータベースですが、データベースをそのまま扱うクラスはデータベースマネージャーで問題ありません。

    しかし、扱うデータをデータベースから分離する事で問題の単純化が図れる場合があります。その時にはデータベースマネージャーをプログラム全体に渡って使うのではなく、ユーザークラス、商品クラス、発注クラスを作り、データベースマネージャーを隠蔽するべきです。

    それをせずしてマネージャーに全て任せることこそが忌避されていることで、言葉の響きや和訳のニュアンスはまた別の問題であろうと考えます。

    キャンセル

  • 2016/07/11 14:24

    ユーザークラス、商品クラスなどを作るという話は普通によくやることなので理解できていますが、質問文にある通り、こちらのAPIの操作を簡単にするためのクラスの話を前提としてしています。https://developers.google.com/apps-script/reference/spreadsheet/

    キャンセル

  • 2016/07/11 14:30 編集

    マネージャーが忌避される要件ではないところで忌避するのはやり過ぎかと。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問