設計原則
一般的な設計原則の概要
SOLID
- 単一責任の原則(SRP): クラスは単一の責任だけを持つべきです。 すなわち、ソフトウェアの仕様の一部分の変更のみが、クラスの仕様に影響を与えることができるべきです。
-
- 開放/閉鎖原則(OCP): “Software entities … should be open for extension, but closed for modification.(ソフトウェアエンティティは … 拡張に対して開放され、変更に対して閉鎖されているべきです)”
- リスコフの置換原則(LSP): “Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.(プログラム中のオブジェクトは、プログラムを修正することなく、 そのサブタイプのインスタンスと置き換え可能であるべきです。”
- インタフェース分離の原則(ISP): “Many client-specific interfaces are better than one general-purpose interface.(多くのクライアント固有のインタフェースは、1つの汎用インタフェースよりも優れている)”
- 依存関係逆転の原則(DIP): “depend upon abstractions, [not] concretions.(抽象的なものに依存すべきであり、具体的なものに依存すべきではない)”。
DRY (Don’t Repeat Yourself)
“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system(すべての知識は、システム内で単一の、曖昧さのない、権威ある表現を持たなければなりません)”
KISSの原則
これでパースに近づけました。エラーケースを無視して、基本的なパーサーが何をするか考えてみよう。繰り返しますが、これが正規形です:
デメテルの法則(LoD)
Rustでは、これは標準ライブラリの2つのトレイト: FromStr
とToString
の組にて実装可能です。Rustのバージョンはエラーも処理します:
契約による設計(DbC)
一見したところ、これはパーサーを記述するための良い選択肢であるように思えます。実際にやってみましょう:
カプセル化
第一に、to_string
はAPIのユーザーに「これはJSONです」ということを示しません。すべての型がJSON表現に対応している必要がありますが、Rust標準ライブラリの型の多くがすでに対応するものでありません。これを使用するのはあまり適格でないでしょう。これは、独自のトレイトで簡単に解決できます。
コマンド-クエリの分離(CQS)
“Functions should not produce abstract side effects…only commands (procedures) will be permitted to produce side effects. (関数は副作用を発生されてはいけません … コマンド(プロシージャ)だけが副作用を発生することを許容されます)” - Bertrand Meyer: Object-Oriented Software Construction
驚き最小の原則(POLA)
システムの構成要素はそのユーザが期待するように振舞わねばならず、その振る舞いはユーザを驚かせるものであってはなりません
言語モジュール単位(Linguistic-Modular-Units)
“Modules must correspond to syntactic units in the language used. (モジュールは使用言語の構文単位に対応しなければならない)” - Bertrand Meyer: Object-Oriented Software Construction
自己文書化(Self-Documentation)
現在サポートしているフォーマットはJSONだけです。より多くのフォーマットをサポートするにはどうすればよいでしょうか?
統一的アクセス(Uniform-Access)
“All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation. (モジュールにより提供されるすべてのサービスは、ストレージによって実装されるのか、計算により実装されるのかを暴露しない、統一された表記法により利用可能であるべきです。)” - Bertrand Meyer: Object-Oriented Software Construction
単一選択(Single-Choice)
“Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list. (ソフトウェアシステムが複数の選択肢をサポートしなければならないときは常に、その網羅的なリストを知っているのはシステム内の単一のモジュールのみであるべきです)” - Bertrand Meyer: Object-Oriented Software Construction
永続的クロージャ(Persistence-Closure)
“Whenever a storage mechanism stores an object, it must store with it the dependents of that object. Whenever a retrieval mechanism retrieves a previously stored object, it must also retrieve any dependent of that object that has not yet been retrieved. (格納メカニズムがオブジェクトを格納するときは常に、 そのオブジェクトに従属するものを一緒に格納しなければなりません。また、取出メカニズムが以前に格納されたオブジェクトを取り出すときは常に、オブジェクトに従属する、また取り出されていないものを取り出さねばなりません。)” - Bertrand Meyer: Object-Oriented Software Construction