LoginSignup
0

More than 1 year has passed since last update.

posted at

共通処理,モジュール

共通処理に関して調べたことのまとめ
検索力がゴミなので浅い内容しかないです。

発端

ginで作ったアプリで通常のログインとユーザ作成後の自動ログイン時の処理をまとめたいということが始まりでした。

一般的な方法

railsだとconcersというディレクトリを各model,controllerなどに追加していくのが一般的らしい。
この際名前に基準はなく日にちに関するものならday.rb、表示リスト(ol,ul)ならhoge_list.rbとか。

Djangoだと書くプロジェクト、各アプリ毎にlibとかを作るようだが実際そこまで細かいルールはないらしい。

laravelは使ったことがないからどんなもんかわからんがぱっと調べたところ特に決まりはなくapp内にcommonとかlibsとかを作っていくっぽい?

後は着眼点としてどのレイヤーの共通処理っていうのもある?
税金の計算を処理するアプリなら

  • 業務レベル(税金関連のビジネスロジック。)
  • DBや通信、ログの作成など(フォームからデータを読み込む、DBから何かする、画面に業務レベルの処理が行ってくれたことを画面に出力するなど。これはDBMSを変更したり、出力形式がjsonからyamlに変わったとかいう差異を吸収する役割もある?)
  • 一般的なこと(日付の計算、数学関連の計算(sin)とか)

日付に関しては1日後の日付を求めるは一般的なことかも知れないがそれが前回の手続きのXXX日後までにYYYをしないといけないとなると日付の計算だが業務レベルに格上げされる。

helper, util, share, mod, lib, common, concern, vendor

helper

インスタンス化してステートを持たせることもできる。

util

状態を持たない一般的なことを扱う。そのアプリだけで使えるというよりどの分野でも使える。
例えばsinの計算など。でもこの場合でもutilは使わず一般的にはmathなどが使われるのでそもそもutilを作らんほうがいい?

share

共有
内部の共有ライブラリを入れるというイメージ?

common

共通・一般
そもそも使わないほうがいい。

mod

機能単体のことを言う?
ライブラリは複数のモジュールからできている。
ただアプリの機能にはちゃんと名前が付いているはずなので使わん。

lib

それだけで完結されている。
かつ特定のドメインに向けて特化されている。
かつ汎用的である。
例えばダミーデータ生成ライブラリ(faker)とか。
後は外部のプログラム。

consern

railsのみの規則っぽい。

vendor

外部のモジュール置き場

モジュール、ライブラリ、コンポーネント
https://medium-company.com/%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB/
パッケージとライブラリ
パッケージはライブラリを使いやすい用にパッケージ化したものという認識。

最初は共通処理の分け方についてだけ調べようと思ったが大体モジュールの良し悪しに関しても記載していたのでそれもメモっとく。

モジュールの分割技法

STS分割

データの取得、
データの加工、
データの保存、
の3つに分割する考え方。

共通機能分割

同じことをやっている処理をモジュール化してまとめる。

モジュールの結合度

各モジュール同士の依存関係は少ないほうがいい。
また依存関係に関してはできるだけ一方通行かつ、循環ができないようにする。(循環は間接的にも起きる)

結合度(Wikiより抜粋)

上に行けば行くほどダメで、下に行けば行くほどよろしい。

手続き型プログラミング

内容結合(Content coupling)「高」
病理学的結合とも呼ばれ、あるモジュールが別のモジュールの内部動作によって変化したり依存したりする(例えば別のモジュールの内部データを直接参照する)。したがって、あるモジュールのデータを生成する方法(場所、種類、タイミング)を変更することは、依存するモジュールの変更につながる可能性がある。

ちょっとよくわからんが例えばオブジェクトAのメソッドaでオブジェクトBのメソッドbを呼び出しbの中でAのメソッドcを呼び出しその中でBのメソッドdを呼び出しているみたいな状態?

共通結合(Common coupling)
グローバル結合とも呼ばれ、二つのモジュールが同じグローバルデータ(例えば、グローバル変数)を共有する。共通のリソースを変更すると、それを使用したすべてのモジュールを変更することを意味する。

外部結合(External coupling)
二つのモジュールは、外部から供給されたデータ·フォーマット、通信プロトコル、またはデバイスインターフェイスを共有している場合に起こる。 これは基本的に外部ツールやデバイスへの通信に関連している。

例えば同じjsonという形式に依存しているときにyamlに帰る、もしくはjsonに新しいデータを追加するということが起きたときに片方の都合による変更がもう片方にも影響を及ぼす必要が出てくる。なので中間クラス(json・yamlからプログラム上のデータ形式に、次に各モジュールで必要なデータ形式に)
後は外部ライブラリ自体の依存という観点もあるらしい外部モジュールに依存すると変更に付き合わないといけない。

制御結合(Control coupling)
あるモジュールに何をすべきかについての情報(例えば、処理を制御するためのフラグ)を渡すことで、別のモジュール処理の流れを制御する。

引数などを使って意図的に処理の制御フローを変更することができる。

スタンプ結合(Stamp coupling)
複数のモジュールが複合データ構造を共有し、その一部のみを使用する(例えば、全レコードの中の1つのフィールドを必要とする関数に全レコードのデータの構造体を渡す)。異なる部分も使用可能。これは、モジュールが必要としないフィールドが変更されることにより、モジュールのレコードを読み取る方法を変更することにつながる可能性がある。

必要最低限のものしか渡さない。

データ結合(Data coupling)
モジュールを介してデータを共有する場合、例えば、引数である。 各データは基本部分であり、これらは単純なデータの受け渡しのみを行う(例えば、数値を渡してその平方根を返す)。

メッセージ結合(Message coupling)「低」
最も結合度が低い結合の種類である。(引数のない)メソッドの呼び出し。メッセージパッシング。

無結合(No coupling)
モジュールが相互に全く通信を行わない。

オブジェクト指向プログラミング

サブクラス結合(Subclass Coupling)
子クラスとその親クラスとの間の関係で、子クラスは、その親クラスに依存しているが、親クラスが子クラスを知らない状態。子クラスが親クラスに依存しすぎると、親クラスを修正するのが難しくなる。

これは多分親クラスから子クラスへの依存の場合何か変更があった場合どれか1つ子クラスへの変更ですむが、子が親へ依存していた場合兄弟クラスへの影響も考えないといけないということを言っている?

一時的結合(Temporal coupling)
あるメソッドが別のメソッドに依存すること(例えば、executeしないとerrorが取得できない)。

例えばcheckhoge関数を読んでからでないとisHogeの値が正しくないとか。
でもよくないと言われてもどうすればいいんや。文句だけ言われて解決法が言われてないんや。

その他

データ結合をメッセージ結合にするにはオブジェクト思考的で考えるならオブジェクトの変数にするという方法があるがそうすると一時的結合が生じる。あるメンバー変数をセットしないと動かないとか。
https://qiita.com/eKushida/items/39bdb3f88fb68ecd66f6
これは1つの例だがもっといろんなひとがこういう観点があるとか、こうすれば達成できるとか書いてくれてるので暇なときに「モジュール 結合度」などと調べるとよし。

凝縮度(Wikiより抜粋)

凝集度は品質尺度であり、ソースコードを調査検討することで凝集度の程度が分類される。低い凝集度から高い凝集度までを以下のように分類できる:

偶発的凝集(Coincidental Cohesion)「最悪」
適当(無作為)に集められたものがモジュールとなっている。モジュール内の各部分には特に関連性はない(例えば、よく使われる関数を集めたモジュールなど)。

よく使われる関数を適当に集めたもの。utilsとかの共通処理を使うときにこんなふうになってないか気をつける。

論理的凝集(Logical Cohesion)
論理的に似たようなことをするものを集めたモジュール(例えば、全ての入出力ルーチンを集めたモジュールなど)。

ユーザデータの読み込みモジュールとDB読み込みモジュールが同じIODataとかに入ている。

時間的凝集(Temporal Cohesion)
動作させたときにモジュール内の各部分が時間的に近く動作する(例えば、ある例外を受けたときに動作するルーチンとして、ファイルをクローズするルーチン、エラーログを作成するルーチン、ユーザーに通知するルーチンなどを集めたモジュール)。

手続き的凝集(Procedural Cohesion)
ある種の処理を行うときに動作する部分を集めたモジュール(例えば、ファイルのパーミッションをチェックするルーチンとファイルをオープンするルーチンなど)。

通信的凝集(Communicational Cohesion)
同じデータを扱う部分を集めたモジュール(例えば、同種のレコードの情報を操作するルーチンを集めたモジュールなど)。

逐次的凝集(Sequential Cohesion)
ある部分の出力が別の部分の入力となるような部分を集めたモジュール(例えば、全体としてあるファイルを読み込んで処理をするモジュール)。

機能的凝集(Functional Cohesion)「最善」
単一のうまく定義されたタスクを実現するモジュール(例えば、角度のサインを計算するモジュール)

凝集度は必ずしも上記の順に高いとか低いと言えるものではない。Larry Constantine やエドワード・ヨードンや他の人々の研究によると、上記の最初の2つは他の凝集よりも劣っており、通信的凝集以下の3つはそれ以外よりも優れている。いずれにしても7番目の機能的凝集が最も優れているとされる。

機能的凝集が最も好ましいとしても、現実には実現できない場合があるだろう。状況によっては通信的凝集が最善であることも多い。いずれにしても通信的凝集以下の3つの凝集では、モジュールを構成するコードが特定の機能を実現するために集中していて無駄がない傾向が強く、様々な状況で再利用の可能性が広がる。

結論

普通にauthenticationディレクトリを作ってそこにまとめることにする。
ユーザー認証による接続状態を作成、センションを開始する操作をログイン
ユーザー認証による接続状態を絶ち、セッションを終了する操作をログアウト

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0