はじめに:
学習過程では技能を熟练掌握するだけでなく、理論の消化吸収も不可欠です。个人としては技術的なものを学ぶことを好みます(短時間の精力投入ですぐに成果が見えます...)が、多くの先輩の経験まとめを見てから、理論的なものは決して軽視できないことを知りました。理論は実践に対して重要な指導意義を持っているからです。「設計」関連のことを理解することは、「実装」に対して潜移默化の影響を与えます。短時間で让人欣喜の変化を見ることはできませんが、ある日振り返って「哦~、原来我这个不错的小习惯は当年あの本で学んだものだ」と思うかもしれません
一。デザインパターンとは何か?
一圈回ってまたこの話題に戻りましょう(本を読む前に自分に一度問いかけ、読み終わった後にもう一度自分に問いかける。答えの差異が感悟です)
之前:
自問:デザインパターンとは何か?
自答:システム設計の指導原則でしょう。でも私は毎日コードを書いているので、設計レベルのものは必要ないでしょう。
自問:哦、では具体的には何か?
自答:不清楚。でも先輩のコードを見たことがあります。構造が非常に複雑で、一看就很上档次的那种。あれはデザインパターンを使ったのでしょう。だからコードがデザインパターンを応用しているかどうかが高手と新手の違いでしょう。私が高手になったら、这种东西还不信手拈来。嗯、不说了、コードを書きに行きます。しっかりプロジェクト経験を積みます。
之后:
自問:デザインパターンとは何か?
自答:デザインパターンはコード構造最適化の経験から抽出された理論知識です。成熟したデザインパターンを応用することで、コードの再利用性、拡張性、保守性を強化できます。
自問:とても専門的に見えますね。では、デザインパターンに这么多利点があるなら、デザインパターンを応用した設計はすべて良い設計ですか?
自答:もちろん違います。パターンを使うためにパターンを使って��いけません。デザインパターンは乱用してはいけません。デザインパターンを応用するには必ずいくつかの犠牲を払う必要があります(例えばクラス構造の複雑さを増すなど...)。だからデザインパターンを乱用すると問題が起きます。しかも、ハンマーを持っても、すべての問題を釘と見てはいけませんよね?
P.S. 正規表現を学んだまとめを覚えていますか:使わなくて済むならできるだけ使わない(最大限度的に乱用を避ける)。デザインパターンもこれに似ています。什么问题もパターンに頼ってはいけません。現在の状況で確かにデザインパターンで設計を最適化する必要があると非常に確定している時にのみ、デザインパターンの使用を検討します(使うかどうかは、リファクタリングのコストと最適化の収益を衡量する必要があります...)
二。デザインパターンを使うべきか?
これは考える価値のある問題です。今私たちはハンマーを持っています。それを使うべきかは問題になります。すべての問題がハンマーで解決できるわけではないからです。一歩譲って、すべての問題がハンマーで解決できるとしても、ハンマーを使うのが最良の解決策かどうかは分かりません(釘を抜くなら、ペンチの方が良いかもしれません...)
あるデザインパターンをコードに入れようとする時、最好は利弊を衡量しましょう。確かに、デザインパターンが持つ設計上の弾力性は、その後の維持変更にいくつかの便利さをもたらします。しかし利点と欠点のどちらが多いかは、いくつかの質問に答えてから決める必要があります:
- 私たちのプロジェクトはほとんど維持に関係しないか、後続バージョンがないなら、デザインパターンを導入する必要性はありますか?
- 私たちのプロジェクトの規模は、デザインパターンを使わなければならないほど大きいですか?
- このデザインパターンはここで使うのに適していますか?もっと適したものはありますか?
- 必ずデザインパターンを使う必要がありますか?いくつかのシンプルな設計原則で代用できませんか?
- デザインパターンを導入した後、コード構造の複雑さが大幅に増加します。リファクタリングのコストは受け入れられますか?
深く考えた後、やはりデザインパターンを使う方が良いと思うなら、安心して使いましょう。その後デザインパターンがもたらす利点を楽しみましょう
三。設計原則まとめ
設計原則はすべてシンプルな指導意見で、固定された実装がありません。だから設計原則はより柔軟です。一般的な設計原則は以下の通り:
- 変化をカプセル化する(変化しやすい部分を取り出し、他の部分への影響を減らす)
- 継承よりコンポジションを多用する(コンポジションは継承より弾力性がある)
- インターフェースに対してプログラミングし、実装に対してプログラミングしない(インターフェースを使うことで具体的なクラスへの直接依存を避けられる)
- 相互作用オブジェクト間の疎結合設計に努める(より疎な結合はより多くの弾力性を意味する)
- クラスは拡張に対して開き、修正に対して閉じるべき(open-close 原則)
- 抽象に依存し、具体的なクラスに依存しない(具体的なクラスへの直接依存を減らす)
- 友人とだけ話す(親友原則)
- 私を呼ばないで、私があなたを呼びます(Don't call me, I will call you back. アンドロイド開発の大原則)
- クラスは変更する理由が 1 つだけであるべき(単一責任原則)
設計原則で解決できる問題はデザインパターンを使わないでください(鶏を殺すのに牛刀を使う必要はありません...)。設計原則は実装がより柔軟で、より軽量だからです(パターンの条条框框を考慮する必要がありません...)
四。デザインパターンまとめ
| 名称 | 特徴 |
| 戦略パターン(Strategy) | 置換可能なアルゴリズムステップを 1 つずつアルゴリズムファミリーとしてカプセル化し、実行時に動的に選択 |
| オブザーバーパターン(Observer) | オブジェクト間の 1 対多の関係を定義し維持 |
| デコレーターパターン(Decorator) | 共通スーパークラスを持つデコレーターと被デコレーターを建立し、機能の動的拡張を実現 |
| ファクトリーパターン(Factory) | オブジェクトの作成プロセスをカプセル化。ファクトリーメソッドパターンと抽象ファクトリーパターンを含む |
| シングルトンパターン(Singleton) | 唯一のオブジェクトを作成するために使用(データベース接続オブジェクト、スレッドプールオブジェクトなど) |
| コマンドパターン(Command) | メソッド呼び出しの詳細をカプセル化。リクエスターとエグゼキューターをデカップリング |
| アダプターパターン(Adapter) | 異なるインターフェース間の変換を実現するために使用 |
| ファサードパターン(Facade) | 複雑なサブシステムに対してシンプルで使いやすい高レベルインターフェースを提供 |
| テンプレートメソッドパターン(Template Method) | アルゴリズムの骨格(フロー)をカプセル化するために使用。いくつかのステップはサブクラスが実装 |
| イテレーターパターン(Iterator) | トラバースの詳細をカプセル化するために使用 |
| コンポジットパターン(Composite) | 階層構造を提供。オブジェクトとオブジェクトコレクションの差異を無視し、一視同仁に扱えるようにする |
| ステートパターン(State) | すべてのアクションをステートオブジェクトにカプセル化。ステートホルダーは動作を現在のステートオブジェクトに委譲 |
| プロキシーパターン(Proxy) | 第三者(プロキシーオブジェクト)を挿入して呼び出し者と被呼び出し者を分離(エグゼキューターとは異なる) |
| 複合パターン(Compound) | 複数のパターンを組み合わせて 1 つの「フレームワーク」を形成し、一般的な問題を解決 |
| ブリッジパターン(Bridge) | 抽象的な制御クラスと具体的な実装クラスをコンポジションを通じてデカップリング。抽象層クラスと実装層クラスが互いに対して独立して変化できるようにする |
| ビルダーパターン(Builder) | コンポジション構造(ツリー構造)の構築プロセスをカプセル化するために使用。イテレーターパターンと同様に、コンポジション構造の内部実装を隠蔽し、コンポジション構造を作成するための一組のインターフェースのみを提供 |
| 責任の鎖パターン(Chain of Responsibility) | 1 つのリクエストを一組の受信者が順次処理できるようにする。Android のリクエスト処理方式に類似:1 つの受信者がリクエストをキャプチャした後、return true でリクエストを消費するか、return false で受信者キュー中の次の受信者(オブザーバー)に渡す |
| フライウェイトパターン(Flyweight) | オブジェクト管理層を抽象化して大量の同タイプオブジェクトを统一管理。実行時オブジェクトインスタンスの数を減らし、メモリ消費を削減 |
| インタプリターパターン(Interpreter) | シンプルな言語のためにインタプリターを作成するために使用。文法規則を直接各クラスにマッピング。構造はシンプルだが、効率は低い |
| メディエーターパターン(Mediator) | メディエーターを導入して複数のオブジェクト間の複雑な相互作用をカプセル化。同級(クラス構造の統一レベル上の)オブジェクト間の依存を低減 |
| メメントパターン(Memento) | オブジェクトステートの保存と回復をサポート。オブジェクトステートデータをカプセル化し、顧客コードから独立して保護を提供(Java ではシリアライゼーション・デシリアライゼーション技術と組み合わせてこのパターンを実装可能) |
| プロトタイプパターン(Prototype) | 既存のオブジェクトをプロトタイプとし、clone を通じて新しいオブジェクトを取得(新しいオブジェクトの作成プロセスを簡素化) |
| ビジターパターン(Visitor) | コンポジション構造に新しい操作を追加。コンポジション構造を頻繁に変更する必要がない |
五。オブジェクト指向設計(Object Oriented Design)
OOD に常に伴う問題は「折衷」(または「取舍」)です。最もシンプルな例——デザインパターンを使うべきか?
- 使う:複雑なクラス関係、多層の抽象を生むことを意味。可読性を犠牲にして拡張性、保守性或者其他特性を獲得
- 使わない:既存コードをリファクタリングする必要がない(または複雑な設計に过多の時間を費やす必要がない)ことを意味。しかしデザインパターンのすべての利点を得ることはできません
二者択一、これが「取舍」です。または第三のオプションを作成する(例えば設計原則を使う)。これが「折衷」です
おわりに:『Head First デザインパターン』について
書評を書くことはめったにありません。人それぞれの好みがあるので、推薦しにくいからです(時には本を好きになるのは著者の文章スタイルを好きなだけということもあり、無意識に書籍内容が良いと思うこともあります...)
この本は先輩に推薦されました。読み終えた後、大部分の章はとても良く書かれていると感じました。細かくて通俗的です。しかしいくつかの章はあまり良くないと感じました(例えば第 1 章の戦略パターンの例はあまり適切ではなく、後のリモートプロキシー部分の詳細展開が不合理など)
総体的に言えば、入門書籍として、『Head First デザインパターン』は还是不错的。個人の感想です。参考までに
コメントはまだありません