1

これは一般的なソフトウェア設計の問題です。

複数のプラットフォームをサポートするには、#if コンパイラ ディレクティブを使用することをお勧めします。たとえば、次の 3 つのファイルがあります。

IScreen.cs

public interface IScreen {
   ...
}

ScreenWin.cs

#if WIN

public class Screen : IScreen {
  ...
}

#endif

ScreenMac.cs

#if WIN

public class Screen : IScreen {
   ...
}

#endif

これについて素晴らしいと思われるのは、BDD を使用して次のようなものを作成できることです。

Given a Screen exists with width: 1920 and height: 1080

また、コンパイラ ディレクティブに基づいて正しい画面が使用されます。

これにより、抽象ファクトリを使用するよりもパフォーマンスが向上するようです。

いくつかの欠点は何ですか?

4

2 に答える 2

2

@Odedが答えたように、コンパイル時のディレクティブを使用することの欠点は、プラットフォームごとに特定のバイナリをコンパイルする必要があることです。良い面は、プラットフォームに依存しないという理由だけで、すべてのプラットフォームで大きくて遅い、肥大化した画一的なアプリケーションを持っていないことです。

#if のもう 1 つの欠点は、多くの Visual Studio ツールが "現在アクティブな" コードのみを考慮することです。たとえば、インテリセンスとリファクタリング ツール - IScreen の名前を IDisplay に変更したい場合、リファクタリングが機能し、すべての PC コードが完全に更新されていることがわかりますが、すべての Mac コードはひどく壊れているでしょう。他のコード ブランチを参照してください。同様に、PC ブランチのコードに変更を加えると、対応する変更を Mac ブランチに加えることを忘れて、再びコードが壊れてしまいがちです。

「#if」の代わりにファクトリを使用する利点は、単一のバイナリ イメージをすべてのプラットフォームで実行できる可能性があり、具体的な実装を作成するときにホスト プラットフォームを 1 回確認するだけでよいことです (したがって、実行時には非常に効率的ですが、 1 つのディストリビューション内ですべてのプラットフォーム バリアントを出荷する必要があるため、サイズが大きくなります)。

ただし、#if の代わりに、よりモジュール化されたデザイン パターンを使用することで、両方の長所を活かすことができます。プラットフォーム固有の実装にはサテライト アセンブリを使用します。このアプローチでは、メイン アプリケーション コードでIScreen インターフェイスを指定し、 Concrete Screen(Mac) とScreen(PC) ScreenImplementation.dll アセンブリの個別のプラットフォーム固有のバリアントのクラス。すべてのプラットフォームをカバーする単一のインストーラーを出荷することもできます (ホスト プラットフォームに適切なサテライト dll を展開するだけです)。これにより、#if を使用した場合のわずかな効率/サイズの改善が得られますが、実際にコードを条件付きで台無しにする必要はありません。(もちろん、このモジュラー アプローチは #if 設計と Factory 設計の両方で理にかなっています。プラットフォーム固有の実装を個別のアセンブリに分割すると、コア実装アーキテクチャではなく、展開オプションになります)

于 2011-03-26T21:58:54.233 に答える
1

欠点には、複数のバイナリ (プラットフォームごとに 1 つ) をコンパイルする必要があることが含まれます。

注意しないと、コードの多くの部分でプリプロセッサ ディレクティブを使用してコードが乱雑になる可能性があります。そのようなコードベースの 1 つを元に戻すことについては、このSO の質問を参照してください。

コード内でプラットフォームを検出できる場合は、より良いアプローチです。

于 2011-03-26T20:41:40.370 に答える