入社したばかりの新しい会社のコードベースを調べていると、今まで考えたこともなかったことがわかりました。基本的にこれが起こります。たとえば、異なる画像タイプ間で変換するためのいくつかの抽象メソッドを持つ Image を表す基本クラスがあります。さまざまな画像タイプは、基本 Image クラスのサブクラスです。サブクラスは、すべて派生クラスである異なる画像間の変換を担当します。
私の質問は、これは良いデザインであるはずですか? そうでない場合、どのような選択肢がありますか?
どうもありがとう。
これは最も洗練された構造ではありませんが、扱う画像の種類が少ない限りは機能します。変換を共通の基本クラスの汎用機能に移行すると、より洗練され、追加の画像タイプに対してよりスケーラブルになります。欠点は、変更を導入することであり、独自の設計上のトレードオフがいくつかあります。
主なアーキテクチャ上の問題は次のとおりです。
これらのオプションはすべて、実際に見つけることができます。
各画像クラス内で変換を行う現在の設計は、多くの言語でかなり基本的なデータ型/クラスを反映しています。それらはそれぞれ、シリアライズ、表現、または他のいくつかの形式 (たとえば、文字列、pickle などの通信形式) に変換できることが期待されています。ただし、型が数個以上ある場合、X から Y へのコンバーターを作成すると、すぐに管理不能になります。n(n-1) 個の変換方法が必要になります。「誰もそんなことをする時間はない!」
一方、netpbmやpandocなどのすべての変換および操作スイートは、一般的な中間表現を使用することがよくあります。私があなたの状況に最も近い類似物であるPython の PIL/Pillow のようなイメージング ライブラリは、多くのImage
場合、独自の on-ディスクフォーマット。
抽象化は常に不完全です。X または Y だけを扱っている場合、継承は適切です。しかし、タイプ X とタイプ Y の複雑さを同時に処理する必要がある場合、完璧な答えはありません。さらにクラスを分解しても役に立ちません。多重継承もありません。
パラダイムとおそらく最良の全体的な答えは、変換を基本クラスに移動することです。しかし、これには独自のトレードオフがないわけではありません。次に、基本クラスは、可能なすべてのサブクラスの変換について認識し、対応する必要があります。そのため、アルファ チャネル、CLUT、Z バッファ、ガンマ補正テーブル、HDR キャリブレーション情報、およびその他のデータ/メタデータを持たない形式を変換する場合でも、基本クラスのメソッドとデータ構造が認識して対処する必要があります。もしあればそのようなものでそれらのサブクラスにはそれらのものがあります。変換をアップスタックにプッシュすると、基本クラスとサブクラスの間で (設計時と実行時の両方で) ピンポン通信が発生する可能性があります。これは、基本メソッドがサブクラスに問い合わせたり、タスクを委任したりするためです。しかし、住宅転換アップスタックに関するこれらの懸念は二次的な問題です。実際に遭遇しない限り、そして遭遇するまでは、それほど厄介ではありません。
したがって、正味のアドバイスは次のとおりです。いくつかの画像タイプの場合、変換は各画像クラスで合理的に実行できます。これは、すでに「鳥を手にしている」場合に特に当てはまります。つまり、すでにこのアプローチを採用している、動作するテスト済みのコードです。ただし、デザインを「クリーンアップ」したい場合は、インポート/エクスポート/変換を基本クラスに移行する方がより洗練されており、追加の画像タイプに対してよりスケーラブルです。(その行進を開始する前に、既存の実装で適切な単体テストを実施して、第 2 世代のコードを簡単に評価できるようにしてください。)