質問するログイン新規登録

Q&A

解決済

6回答

14331閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

命名規則

命名規則は、プログラミングする際に識別子の名称である文字列を決める表記法のことです。ネーミング規則・ネーミング規約・命名規約とも呼びます。

1グッド

3クリップ

投稿2016/07/10 05:11

編集2016/07/11 05:14

1

3

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

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

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

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

TypeScript

1let spreadSheetManager: SpreadsheetManager = new SpreadsheetManager("スプレッドシートファイルID"); 2spreadSheetManager.selectSheetByName("シート名(タブ名)"); 3spreadsheetManager.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?

stereo_codeが👍を押しています

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

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

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

guest

この質問の投稿者はすでに退会しているため、質問者からの返信がない点にご留意ください。

回答6件

0

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

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

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


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

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

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


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

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

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

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


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

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

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

投稿2016/07/10 13:32

LLman

総合スコア5594

退会済みユーザー

退会済みユーザー

2016/07/11 05:28 編集

ご回答ありがとうございます。 "質問文に「メソッドを外部に公開する」とありますが、 ファサードは受付なので窓口越しに指図したりしません。 " ↑ これはファサードクラスのメソッドを外部に公開するという意味で書いています。内部で利用している複数のAPIのクラスを利用者が直接呼べるという意味ではないです。 "三択なら「~Wrapper」を選びます。 今回のイメージに近い素直な命名で分かりやすいです。 " ↑ なるほど。SpreadsheetWrapperみたいな名前が良いのですかね。xxxWrapperというクラス名の場合、xxxクラスのみをWrapしてるクラスという風に一般的には捉えられてしまうものなのでしょうか?内部で複数のクラスを利用している場合は不適切でしょうか?
guest

0

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

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

であると思います。

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

話がそれました。

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

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

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

Manager と Facade の違いですが、

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

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

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

投稿2016/07/11 04:45

編集2016/07/11 05:00
amay077

総合スコア1075

退会済みユーザー

退会済みユーザー

2016/07/11 04:53

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

0

ベストアンサー

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 と命名する事で汎用クラスと誤認されるリスクをなくすことが出来ます。

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

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

JavaScript

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

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

更新履歴

  • 2016/07/11 12:34 GoogleSpreadsheet, GoogleSpreadsheetReader の説明を追記

Re: hayatomo さん

投稿2016/07/11 02:58

編集2016/07/11 03:34
think49

総合スコア18198

退会済みユーザー

退会済みユーザー

2016/07/11 04:34

ご回答頂きましてありがとうございます!非常に参考になりました。 "まず、考えるべきは「新しく作られるラップ関数が SpreadsheetApp の全ての機能を網羅しているか」という事です。" ↑ そうなんです!ここも自分的にモヤモヤとしていたポイントだったのです。先ほど質問文に補足として追加しましたが、サンプルコードであるSpreadsheetManagerクラスはSpreadsheet Service全体の機能を網羅している訳ではないのです。該当クラスの場合であれば、開いたシートの読み書きを行います。 サンプルコードの最後の行のappendTableDataというメソッドは選択されているシートの最後の行の次の行に、二次元配列のデータを渡して書き込みを行うといったメソッドです。 SpreadsheetAppクラスには他にもカスタムメニューやダイアログボックスを生成するためのUI関連のメソッドもあるのですが、そのUI関連のメソッドはまた別のラッパークラスを作って、単純なインターフェイスで利用者が使えるようにしたいと考えています。
退会済みユーザー

退会済みユーザー

2016/07/11 04:41 編集

"つまり、既存シートの読み込みに特化しており、書き込み機能はないのでしょう。 " ↑ 先のコメントでも書いた通りなのですが、既存のシートの読み込みと書き込みする機能はあります。逆にSpreadsheetAppクラスにあるような、新規のスプレッドシートファイルを作成したり、Google Driveから特定のスプレッドシートファイルを検索したりする機能はありません。 "従って、SpreadsheetReader と命名できます。 前述の理由で GoogleSpreadsheetReader と命名すると更にわかりやすいと思います。" ↑ やはり方向性としては、質問文からリンクしていた記事の中でも書かれていた通り、「手段と目的を履き違へるべからず。「ラッパーであること」や「プロクシであること」は何か他の目的を実現するための手段に過ぎないはず。」ということを意識して、wrapperやfacadeのようなクラス名よりは、より具体的な名前をつけることを検討してみたいと思いました!となると、良い名前が何なのか迷ってしまって、コードを書く手が止まってしまったりしますが、良い機会なので考えてみたいと思います!
guest

0

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

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

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

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

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

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

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

投稿2016/07/10 08:52

iwamoto_takaaki

総合スコア2884

退会済みユーザー

退会済みユーザー

2016/07/10 10:46

ご回答ありがとうございます! "ファザードを使う場合には、内部を徹底して隠蔽して内部のオブジェクトに一切触れさせないことが必要です。" ↑ こちらの一文をみて、掲載したサンプルコードを見てみましたら、なぜか、SpreadsheetManagerクラスをインスタンス化すると、なぜか、SpreadsheetManager型ではないインスタンスを返して初期化するコードになってました。これは誤表記で実際は修正したサンプルコードのようなものです。 ファサードの場合は、内部のオブジェクトに触らせない、拡張し過ぎないが原則なのですね。
guest

0

こんにちは。

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

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

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

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

投稿2016/07/10 05:43

Chironian

総合スコア23279

退会済みユーザー

退会済みユーザー

2016/07/10 06:02

ご回答頂きましてありがとうございます! "本当に複数のxxxの存在を保持したり、それぞれの状態を保持したりしますか?" ↑ 掲載したサンプルコードの例の場合、SpreadsheetManagerを初期化した時にSheet型のインスタンスをプライベートプロパティに代入しますが、リストに追加してる訳でもなく、単一のSheet型インスタンスを保持してるだけですね。 となると、Managerという接尾語をクラス名につけるのはおかしいということになりますね。。 ラッパーの場合、どんなクラス名が適切なのでしょうか。掲載したサンプルコードの例では、Facedeでしょうか。
Chironian

2016/07/10 06:15

Facadeってあまり聞き慣れない単語のような気がします。Weblioでみると「(建物の)正面、(しばしば実体よりりっぱな事物の)見かけ、外見」で良く意味が分からんです。 単にxxxWrapperではダメでしょうか? しかし、hayatomoさんのプロジェクトに関係する皆さんが、Facadeという単語に慣れていて、かつ、Wrapperより意味的に正確ならFacadeの方が良いと思います。
退会済みユーザー

退会済みユーザー

2016/07/10 07:49

facadeはデザインパターンのファサードのことです。wrapperか今回の場合であればfacade、このどちらかがmanagerよりも適切ということなのですね。ありがとうございます!
Chironian

2016/07/11 03:28

FacadeパターンのWikipediaの説明を見てみました。 いくつかの機能を組み合わせてより高度な機能を提供する設計のことですね。 Wikipediaの説明を見る限り、一般的なモジュール分割の話かと。(聞き慣れない名前を付けて混乱させているだけのような気がしないでもないです。) ということは、Facadeという接尾詞をつけるのはあまり適切ではないと思います。 普通によく使われる構造の名前を付けてもソースを読む人にあまり有効な情報が伝わりません。その「より高度な機能」の名前を付けた方が可読性が上がると思います。 しかし、今回の場合は、SpreadsheetAppなどを組み合わせてより高度な機能を提供しているわけではなさそうですので、そもそもFacadeパターンではないような印象を受けます。
退会済みユーザー

退会済みユーザー

2016/07/11 04:03

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

退会済みユーザー

2016/07/11 04: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
Chironian

2016/07/11 06:42

> facadeパターンでは高度な機能を提供する必要はなかったと思います。 あ、定義的にはその通りすね。 複数の機能を組み合わせるので通常はより高度になるとは思いますが、議論の本質ではないのでどちらでも良いです。 サブシステムの機能と異なる機能を提供するのであれば、その新たな機能名をつけた方が良いと思います。 サブシステムと同じ機能を提供するバターンはFacadeパターンには含まれないと思います。 > 手段と目的を履き違へるべからず。 一見、適切な印象の文ですが、命名する時に当てはめるのはよろしくないと思います。 命名は、対象物の特徴を最も適切に表現する言葉を選ぶべきです。その言葉が目的を表す場合もあれば手段を表す場合もあります。 バブル・ソートとかバイナリー・ソートとか手段も名前に含んでますが、分かりやすい命名と思いますよ。
guest

0

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

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

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

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

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

投稿2016/07/11 04:21

編集2016/07/11 04:42
Zuishin

総合スコア0

退会済みユーザー

退会済みユーザー

2016/07/11 04:54 編集

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

2016/07/11 05:16

どうしてもシートの拡張として扱わなければならないというのであれば、マネージャーであろうが他の何であろうが同じだと思います。 なぜマネージャーが嫌われるのか、単に言葉の響きだとお思いですか?マネージャーをファサードに変えたらそれは解決しますか? シートはいわゆるデータベースですが、データベースをそのまま扱うクラスはデータベースマネージャーで問題ありません。 しかし、扱うデータをデータベースから分離する事で問題の単純化が図れる場合があります。その時にはデータベースマネージャーをプログラム全体に渡って使うのではなく、ユーザークラス、商品クラス、発注クラスを作り、データベースマネージャーを隠蔽するべきです。 それをせずしてマネージャーに全て任せることこそが忌避されていることで、言葉の響きや和訳のニュアンスはまた別の問題であろうと考えます。
退会済みユーザー

退会済みユーザー

2016/07/11 05:24

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

2016/07/11 05:33 編集

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

この質問の投稿者はすでに退会しているため、質問者からの返信やベストアンサーの選定がない点にご留意ください。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.25%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問