タグ付けされた質問 「design」

ソフトウェア設計による問題の解決とソリューションの計画に関する質問。

3
合計タイプとポリモーフィズム
昨年、私は飛躍して関数型プログラミング言語(F#)を学びました。私が発見した興味深い点の1つは、OOソフトウェアの設計方法にどのように影響するかです。私がオブジェクト指向言語で最も欠けていると思うのは、パターンマッチングと合計タイプの2つです。どこを見ても、差別的な組合で簡単にモデル化される状況が見られますが、パラダイムに不自然に感じられる一部のOO DU実装でバールを表示することに抵抗があります。 これにより、通常or、合計タイプが処理する関係を処理する中間タイプを作成するようになります。また、かなりの分岐につながるようです。Misko Heveryのような人を読んだ場合、優れたOOデザインは多態性による分岐を最小限に抑えることができると彼は示唆しています。 OOコードでできる限り避けたいことの1つは、null値を持つ型です。明らかに、or関係は1つのnull値と1つの非null値を持つタイプによってモデル化できますが、これはnullあらゆる場所でのテストを意味します。異種であるが論理的に関連付けられた型を多態的にモデル化する方法はありますか?設計戦略やパターンは非常に役立つでしょう。あるいは、一般的にオブジェクト指向のパラダイムで、異種の関連タイプについて考える方法です。

3
Entity FrameworkのDataContextオブジェクトを作成して、各CRUDメソッドのusingブロックに配置しても問題ありませんか?
次の機能を実装するwpfアプリケーションを構築しています。 ユーザー入力を取得し、データベースからデータを読み取る それにいくつかの計算を行います 複数のタイプのビューでユーザーにそれを紹介し、変更をデータベースに書き込みます 提案されたアーキテクチャ:データベース->エンティティフレームワーク->リポジトリ->ビジネスロジック->データサービス-> ViewModel このアーキテクチャを使用する理由:アプリケーション(複数のビュー)と複数のデータベースに存在する複数のシナリオ。したがって、私は抽象化のために真ん中にリポジトリを使用する用意があります。 注意点の1つは、リポジトリが実装されている場合、コンテキストは長期間有効であることです。これを克服するために、コンテキストを作成し、それらを各クラッドメソッドのusing()ブロックに配置しても問題ありませんか? 別のアプローチを提案すること自由に感じなさい。
10 c#  design  architecture  wpf 

2
依存関係の逆転の原則:低レベルコンポーネントと高レベルコンポーネントの両方が抽象化にどのように依存するかを理解する
依存関係の逆転の原理について学習しています。それはそれを述べています: 高レベルのモジュールは、低レベルのモジュールに依存するべきではありません。どちらも抽象化に依存する必要があります。 しばらく、私はそれが高レベルのコンポーネントと低レベルのコンポーネントの両方が抽象に依存し、それらに依存していることの意味を理解しようとしました。 どちらも同じ抽象化に何らかの形で依存する必要があると思います。これが間違っている場合は修正してください。 私はこれが何を意味するかについていくつかの結論に達しています。これが正しいかどうか確認してください。 「高レベルのコンポーネントは抽象化に依存しています」-意味: 高レベルコンポーネントは、具体的な低レベルコンポーネントと直接通信するのではなく、低レベルコンポーネントと通信するためにインターフェースと通信します。低レベルのコンポーネントはこのインターフェースを実装します。 「低レベルのコンポーネントは抽象化に依存しています」-意味: 低レベルのコンポーネントは、インターフェースの観点から定義および設計されています。それらはインターフェイスに合うように設計されています。それらは、インターフェースがそれらの設計方法を定義する方法で、インターフェースに依存しています。(多くの場合、低レベルのクラスがそのインターフェースを実装しています)。 このように、高レベルのコンポーネントと低レベルのコンポーネントはどちらも「抽象化に依存」していますが、方法は異なります。 これはよく理解していますか?

6
懸念の分離について書いたとき、ダイクストラはコードのモジュール化を意図していましたか?
まず、私は1974年の「科学的思考の役割について」の抜粋エズガーW.ダイクストラの論文を読みました。 私にあなたに説明しようと思います、私の好みに何がすべてのインテリジェントな思考に特徴的です。それは、自分の一貫性を保つために、自分の主題の側面を分離して詳細に研究することをいとわないことです。常に、側面の1つだけで自分を占有していることを知っています。私たちはプログラムが正しい必要があることを知っており、その観点からのみそれを学ぶことができます。また、効率的である必要があることもわかっており、いわば、別の日にその効率を調査することができます。別の気分では、プログラムが望ましいかどうか、またそうである場合、なぜプログラムが望ましいかを自問することがあります。しかし、これらのさまざまな側面に同時に取り組むことによって何も得られません-逆に!-。それは私が時々「懸念の分離」と呼んだものであり、それは完全に可能ではないにしても、私の知る限り、思考を効果的に順序付けるために利用できる唯一の手法です。これは、「ある側面に注目する」という意味です。他の側面を無視することを意味するのではなく、この側面の観点から見れば、他の側面は無関係であることを正当化するだけです。それは1つと複数のトラックを同時に気にしています。 私は、コードをモジュール化することについて、現代の懸念の分離が語られているのを見ています。しかし、上記の引用を読んで、私はこれをあなたの心を一度に1つの特定のタスクに集中させ、他の側面に焦点を合わせないものとして理解します。これは、必ずしもコードをモジュール化されたチャンクに分離する必要があることを意味するわけではありません。 つまり、1つのファイルに、ビュー、リポジトリ、コントローラー、イベント処理、ファクトリーなどの概念がすべて1つのファイルにあるというコードが目の前にあるとします。 簡単な例として、データアクセスと表示(出力)を行うコードを次に示します。 $sql = "SELECT * FROM product WHERE id = " . db_input($id); $row = db_fetch_array(db_query($sql)); <option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? ' selected="selected"' : '' ?>>Version <?=$row['ver']?></option> モダンなオブジェクト指向を使用して、リポジトリパターンを使用して独自のファイルにデータアクセスを配置し、ビューコードを独自のファイルテンプレートに入れ、それらをまとめてコントローラー(またはアクションまたはリクエストハンドラー)を介して通信することができます。ファクトリーを追加して、さまざまな依存関係を作成して接続します。そして、それらのファクトリーを定義する構成ファイルを持つことができます。確かに、それは単一ファイルのすべてから一歩離れています。 懸念の分離に関する私の質問は次のようなものです。ダイクストラの引用を読んで、おそらく彼が懸念の分離を必ずしも「コードのモジュール化(ファイルまたは独自の関数/メソッド/その他への)分離」であるとは限らないという考えを得ました。また、コードで物理的に分離されているかどうかに関係なく、他の重要であるが現時点では検討されていない側面に集中することなく、プログラムの側面に集中することを意味しました。 では、なぜ、物理的なモジュラーコードの分離と設計パターンに負担をかけているのでしょうか。コードがどのように構造化されているかに関係なく、アスペクトに専念するだけでは十分ではありませんか? 私は最も恐ろしいスパゲッティコードを書くことについて話しているのではなく、その側面のみを検討しているので、それはおそらく負担になります。しかし、結局のところ、私が目指しているのは、物理的なコード分離を実行する理由であり、側面に精神的に集中する必要がないのに、なぜコードを個別のファイルまたはチャンク(メソッド)に分割するのか、です。 懸念の分離は、肉体的ではなく精神的な運動のままである必要がありますか? 言い換えれば、プログラミングの精神的側面(焦点を当てる)と物理的側面(紙面上のコード)の間に断絶があるべきでしょうか?

2
例外の粒度
私は、次のような彼らは、一般的な例外を好む数人の友人とI.間の論争に実行したClientErrorExceptionとServerErrorException私は物事にもっと具体的に作ることを好むのに対し、例外のフィールドとして詳細に。たとえば、次のような例外がいくつかある場合があります。 BadRequestException AuthenticationFailureException ProductNotFoundException これらはそれぞれ、APIから返されたエラーコードに基づいて構築されています。 例外の利点に従うと、これはJavaにとって慣用的なようです。しかし、私の友人の意見は全く珍しいことではありません。 コードの読みやすさとAPIの使いやすさの点で好ましい方法はありますか、それとも本当に好みに帰着するだけですか?

7
クラスを細かくしすぎていませんか?単一責任原則はどのように適用されるべきですか?
私は3つの基本的な手順を含む多くのコードを記述しています。 どこかからデータを取得します。 そのデータを変換します。 そのデータをどこかに置きます。 私は通常、それぞれの設計パターンに触発された3種類のクラスを使用します。 ファクトリー-あるリソースからオブジェクトを構築します。 メディエーター-ファクトリーを使用するには、変換を実行してから、司令官を使用します。 司令官-そのデータを別の場所に配置します。 私のクラスは非常に小さく、多くの場合単一の(パブリック)メソッドです。たとえば、データの取得、データの変換、作業の実行、データの保存などです。これはクラスの急増につながりますが、一般的にはうまく機能します。 私がテストに来るときに苦労しているのは、結局は密結合テストになります。例えば; 工場-ディスクからファイルを読み取ります。 Commander-ファイルをディスクに書き込みます。 もう1つがないとテストできません。ディスクの読み取り/書き込みを行うための追加の「テスト」コードを作成することもできますが、それから繰り返します。 .Netを見ると、Fileクラスは別のアプローチをとっており、(私の)ファクトリーとコマンダーの責任を組み合わせています。Create、Delete、Exists、Readの機能がすべて1か所にあります。 .Netの例をたどって、特に外部リソースを扱う場合は、クラスを一緒に結合する必要がありますか?結合されたコードですが、意図的です。テストではなく、元の実装で発生します。 ここでの問題は、単一責任の原則をやや熱心に適用したことですか?読み取りと書き込みを担当する個別のクラスがあります。特定のリソース(システムディスクなど)の処理を担当する結合クラスがある場合。

2
これは、C ++の「pImpl」ベースのクラス階層に適したアプローチですか?
インターフェイスと実装を分離したいクラス階層があります。私の解決策は、インターフェイスのハンドルクラス階層と実装の非パブリッククラス階層の2つの階層を持つことです。基本ハンドルクラスには実装へのポインターがあり、派生ハンドルクラスは、派生型のポインターにキャストします(関数を参照getPimpl())。 これは、2つの派生クラスを持つ基本クラスの私のソリューションのスケッチです。より良い解決策はありますか? ファイル「Base.h」: #include <memory> class Base { protected: class Impl; std::shared_ptr<Impl> pImpl; Base(Impl* pImpl) : pImpl{pImpl} {}; ... }; class Derived_1 final : public Base { protected: class Impl; inline Derived_1* getPimpl() const noexcept { return reinterpret_cast<Impl*>(pImpl.get()); } public: Derived_1(...); void func_1(...) const; ... }; class Derived_2 final : …
9 design  c++  c++11 

3
インターフェースが具象クラスに依存することは問題ありませんか?
カスタムエラーハンドラーのJavaでインターフェイスを作成しています。 引数エラーオブジェクトを渡したいのですが、Exceptionクラスの子である必要があります。 定義したクラス名をインターフェイスで使用しても大丈夫ですか? 実装に依存しないという点で、インターフェースを少なくしませんか? 私はこのようなことをやろうとします: public class CustomException { /* ... Implementation ... */ } public interface Interface { void onError(CustomException ex); }

1
コード設計:任意の関数の委任
PPCGでは、King of the Hillの課題が頻繁に発生します。これは、異なるコードボットを互いに対戦させるものです。これらの課題を単一の言語に限定するのは好きではないため、標準のI / Oを介してクロスプラットフォームの通信を行います。 私の目標は、チャレンジライターがこれらのチャレンジをより簡単に書くために使用できるフレームワークを書くことです。次の要件を満たしました。 チャレンジライターは、メソッドが個別の通信のそれぞれを表すクラスを作成できます。たとえば、私たちのGood vs Evilチャレンジでは、ライターはメソッドを含むPlayerクラスを作成abstract boolean vote(List<List<Boolean>> history)します。 コントローラは、前述のメソッドが呼び出されたときに標準I / Oを介して通信する上記のクラスのインスタンスを提供できます。ただし、上記のクラスのすべてのインスタンスが標準I / Oを介して通信する必要があるとは限りません。ボットのうち3つはネイティブJavaボットである可能性があります(Player別の2つが別の言語である場合、クラスをオーバーライドするだけです)。 メソッドは常に同じ数の引数を持つわけではありません(また、常に戻り値を持つこともありません)。 チャレンジライターが私のフレームワークで作業するためにできる限り少ない作業を行う必要があります。 私はこれらの問題を解決するために反射を使用することに反対していません。私はチャレンジライターに次のようなことを要求することを検討しました: class PlayerComm extends Player { private Communicator communicator; public PlayerComm(Communicator communicator){ this.communicator = communicator; } @Override boolean vote(List<List<Boolean>> history){ return (Boolean)communicator.sendMessage(history); } } しかし、いくつかの方法がある場合、これはかなり繰り返しになる可能性があり、定数のキャストは楽しいものではありません。(sendMessageこの例では、可変数のObject引数を受け入れ、を返しますObject) これを行うより良い方法はありますか?

2
データ指向インターフェースへのプログラミング
次のスタイルで記述されたコードベースの一部があります。 // IScheduledTask.cs public interface IScheduledTask { string TaskName { get; set; } int TaskPriority { get; set; } List<IScheduledTask> Subtasks { get; set; } // ... several more properties in this vein } // ScheduledTaskImpl.cs public class ScheduledTaskImpl : IScheduledTask { public string TaskName { get; set; } public …

2
インターフェース分離の原則:インターフェースに大きな重複がある場合はどうすればよいですか?
アジャイルソフトウェア開発、原則、パターン、およびプラクティス:ピアソン新国際版: 場合によっては、クライアントの異なるグループによって呼び出されるメソッドが重複することがあります。オーバーラップが小さい場合、グループのインターフェースは分離したままにする必要があります。共通の関数は、オーバーラップするすべてのインターフェースで宣言する必要があります。サーバークラスは、これらの各インターフェイスから共通の機能を継承しますが、実装するのは1回だけです。 ボブおじさんは、少しの重複がある場合について話します。 大きな重複がある場合はどうすればよいですか? 私たちは持っていると言います Class UiInterface1; Class UiInterface2; Class UiInterface3; Class UiIterface : public UiInterface1, public UiInterface2, public UiInterface3{}; 間にかなりの重複がある場合、我々は何をすべきUiInterface1とはUiInterface2?

2
UMLダイアグラムを使用してコードの編成方法を計画することが不適切なのはなぜですか?
そのため、はい、図が不適切な場合があります。彼らはいつ不適切ですか?それらを検証するためのコードなしでそれらを作成し、それらに従うことを意図している場合。アイデアを探求するために図を描くことには何の問題もありません。 アジャイルソフトウェア開発:原則、パターン、および実践-Robert C. Martin これは正確にはどういう意味ですか?UMLは、「ダイブイン」する前にコードを構造化する方法を計画するのに役立つように設計されていませんか?あなたが思いついた図に従わない場合、それを使用する意味は何ですか? コンテキスト:この章では、ボブおじさんがボウリングゲームのスコアキーパーのUML図を作成します。次に、UML図を調べずに、テスト駆動の方法でプログラムを開発します。結果のプログラムはUMLダイアグラムとは異なり、ボブおじさんは上記の結論に達します。

5
抽象化に依存することに重大な欠点はありますか?
私はこのウィキを安定した抽象化の原則(SAP)で読んでいました。 SAPは、パッケージの安定性が高いほど、抽象的である必要があると述べています。これは、パッケージの安定性が低い(変更される可能性が高い)場合、より具体的であることを意味します。私が本当に理解していないのは、これが事実であるべき理由です。確かにすべての場合において、安定性に関係なく、抽象化に依存し、具体的な実装を隠す必要がありますか?

3
CRUD API:更新するフィールドをどのように指定しますか?
ある種のデータベースに永続化されているある種のデータ構造があるとします。簡単にするために、このデータ構造を呼びましょうPerson。これで、他のアプリケーションがを作成、読み取り、更新、および削除できるようにするCRUD APIを設計する必要がありますPerson。簡単にするために、このAPIが何らかのWebサービスを介してアクセスされると仮定します。 CRUDのC、R、Dパーツのデザインはシンプルです。私はC#のような関数表記を使用します-実装はSOAP、REST / JSON、またはその他の可能性があります。 class Person { string Name; DateTime? DateOfBirth; ... } Identifier CreatePerson(Person); Person GetPerson(Identifier); void DeletePerson(Identifier); アップデートはどうですか?自然なことは void UpdatePerson(Identifier, Person); しかし、どのフィールドを更新するかをどのように指定しますPersonか? 私が思いつくことができる解決策: 常に完全な Personを渡すように要求することができます。つまり、クライアントは次のようにして生年月日を更新します。 p = GetPerson(id); p.DateOfBirth = ...; UpdatePerson(id, p); ただし、そのためには、GetとUpdateの間にトランザクションの整合性またはロックが必要になります。そうしないと、他のクライアントによって並行して行われた他の変更を上書きする可能性があります。これにより、APIがさらに複雑になります。さらに、次の疑似コード(JSONをサポートするクライアント言語を想定)であるため、エラーが発生しやすくなります。 UpdatePerson(id, { "DateOfBirth": "2015-01-01" }); -これは正しいように見えます-DateOfBirthを変更するだけでなく、他のすべてのフィールドをnullにリセットします。 であるすべてのフィールドを無視できますnull。しかし、それを変更しないこと DateOfBirthと、意図的にnullに変更することの違いをどのように作成しますか? 署名をに変更しますvoid UpdatePerson(Identifier, Person, ListOfFieldNamesToUpdate)。 署名をに変更しますvoid …

1
C ++シリアライゼーションデザインレビュー
C ++アプリケーションを書いています。ほとんどのアプリケーションはデータ引用を読み書きする必要があり、これも例外ではありません。データモデルとシリアル化ロジックの高レベルデザインを作成しました。この質問は、これらの特定の目標を念頭に置いて、私のデザインのレビューを要求しています: 任意の形式(rawバイナリ、XML、JSONなど)でデータモデルを読み書きする簡単で柔軟な方法を提供する。al。データの形式は、シリアル化を要求しているコードと同様に、データ自体から分離する必要があります。 シリアル化が合理的に可能な限りエラーが発生しないようにするため。I / Oは、さまざまな理由で本質的にリスクが高くなります。私の設計では、失敗する方法が増えているのですか?もしそうなら、それらのリスクを軽減するために設計をどのようにリファクタリングできますか? このプロジェクトはC ++を使用します。好きでも嫌いでも、言語には独自の方法があり、デザインはその言語に対抗するのではなく、その言語で機能することを目指しています。 最後に、プロジェクトはwxWidgetsの上に構築されます。より一般的なケースに適用できるソリューションを探していますが、この特定の実装はそのツールキットでうまく機能するはずです。 以下は、C ++で記述された非常に単純なクラスのセットであり、設計を示しています。これらは私がこれまでに部分的に書いた実際のクラスではなく、このコードは私が使用しているデザインを単に示しています。 まず、いくつかのサンプルDAO: #include <iostream> #include <map> #include <memory> #include <string> #include <vector> // One widget represents one record in the application. class Widget { public: using id_type = int; private: id_type id; }; // Container for widgets. Much more than …
9 design  c++  c++11 

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.