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

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

2
インスタンスが1つだけのPythonクラス:(単一の)クラスインスタンスを作成するタイミングと、代わりにクラスを使用するタイミング
1回だけインスタンス化されるPythonクラスがある場合、つまり、クラスのオブジェクトは1つだけになります。クラスを直接操作するのではなく、単一のクラスインスタンスを作成する方が理にかなっているのではないかと思いました。 同様の質問がありますが、焦点は異なります。 グローバル変数と関数をクラスにグループ化することです Python固有ではありません。後者は、(Pythonで)クラスもオブジェクトであるという事実を考慮しないことを意味します。 更新: Pythonでは、クラスとオブジェクトの両方で次のことができます。 class A(object): pass A.some_state_var = True # Then later A.some_state_var = False my_a = A() my_a.some_state_var = True # Then later my_a.some_state_var = False そのため、クラスとそのクラスのインスタンスの間の選択が(Pythonで)状態に関するものであるかどうかはわかりません。どちらかで状態を維持できます。 さらに、クラス/クラスインスタンスを作成する動機は、シングルトン要件を強制することではありません。 また、新しいTypeを作成することはそれほど重要ではありません。 動機は、関連するコードとデータをグループ化し、それへのインターフェースを持つことです。これが、最初にクラス図のクラスとしてモデル化した理由です。実装に関してのみ、このクラスをインスタンス化するかどうか疑問に思い始めました。

1
アワビのようなゲームの六角形ボードロジックを効率的に表現する方法
AIをAbaloneゲームに実装する必要があり、関連するすべてのチェックおよび更新ルーチンで多くのリソースを無駄にせずに、Javaを使用してボードロジックを表現する最良の方法は何か疑問に思っています。 さまざまなリストを使用する方が良いですか?Cellオブジェクトのマトリックス?なにか提案を?

5
内部データ構造を常に完全にカプセル化する必要がありますか?
このクラスを考慮してください: class ClassA{ private Thing[] things; // stores data // stuff omitted public Thing[] getThings(){ return things; } } このクラスは、データを保存するために使用する配列を、関心のあるクライアントコードに公開します。 作業中のアプリでこれを行いました。sのChordProgressionシーケンスを格納するクラスがありましたChord(その他の処理も行います)。Chord[] getChords()コードの配列を返すメソッドがありました。データ構造を(配列からArrayListに)変更する必要がある場合、すべてのクライアントコードが破損しました。 これは私に考えさせられた-多分次のアプローチが優れている: class ClassA{ private Thing[] things; // stores data // stuff omitted public Thing[] getThing(int index){ return things[index]; } public int getDataSize(){ return things.length; } public void setThing(int …

6
適切な設計で簡単にするには大きすぎる変更は何ですか?
これはかなり曖昧な質問ですが、適切な設計について読んだときに満足のいく方法で答えられたとは思っていませんでした。 一般に、オブジェクト指向プログラミング、抽象化、因数分解などについて学ぶとき、設計の聖杯-そして、あなたが問題の開発技術を使用していると常に主張する理由-は、プログラムを「変更しやすくする」ことです、「維持可能」、「柔軟」、またはそのような生産的な響きの概念を表現するために使用される同義語のいずれか。ivarをプライベートとしてマークし、コードを多くの小さな自己完結型のメソッドに分割し、インターフェイスを一般的な状態に保つことで、プログラムを完全に簡単かつ優雅に変更できるようになります。 比較的小さな変更の場合、これは私にとってはうまくいきました。クラスがパフォーマンスを向上させるために使用する内部データ構造の変更は大きな困難ではありませんでした。また、テキスト入力システムの再設計やゲームプレイ要素のグラフィックのオーバーホールなど、APIに依存しないユーザーインターフェイスエンドの変更もありません。 これらの変更はすべて、本質的に自己完結型のようです。それらのいずれも、外部コードに関する限り、変更されるプログラムのコンポーネントの動作または設計への変更を伴いません。手続き型であろうと大規模な機能であろうと小規模であろうとOOスタイルであろうと、これらはあなたが適度に良いデザインしか持っていなくても簡単に変更できます。 しかし、変更が大きくて毛深いものになったとき、つまりAPIに変更が加えられたときはいつでも、私の貴重な「パターン」はどれも助けになりません。大きな変化は大きなままで、影響を受けるコードは影響を受けたままで、何時間もバグを生み出す作業が私の前にあります。 だから、私の質問はこれです。適切な設計がどの程度大きな変更を促進できると主張していますか?私には未知の、または実装に失敗した、さらにスティッキーなサウンドの修正を本当に単純にする、またはその約束(非常に多くの異なるパラダイムによって行われたと聞いた)は単に素晴らしいアイデアである、いくつかのさらなる設計技術がありますか?ソフトウェア開発の不変の真実から完全に切り離されていますか?ツールベルトに追加できる「変更ツール」はありますか? 具体的には、私がフォーラムに導かれた問題はこれです:私は解釈されたプログラミング言語(Dで実装されていますが、それは関係ありません)の実装に取り​​組んでおり、クロージャの引数は現在の位置ではなく、キーワードベース。これには、匿名関数を呼び出す既存のすべてのコードを変更する必要がありますが、幸いなことに、私は言語の開発の初期段階(2000行未満)であるため、かなり小さいですが、後の段階でこの決定を行った場合は非常に大きくなります。そのような状況では、設計の適切な先見によって、この変更を簡単にすることができたのでしょうか、それとも特定の(ほとんどの)変更が本質的に広範囲に及ぶのでしょうか?これが何らかの形で自分自身の設計スキルの失敗であるかどうかに興味があります-もしそうなら、私は 明確にするために、私はOOPや一般的に使用されている他のパターンのいずれにも決して懐疑的ではありません。ただし、私にとっては、それらの長所は、コードベースの保守ではなく、元の記述にあります。継承を使用すると、繰り返しパターンを適切に抽象化できます。ポリモーフィズムを使用すると、機械が理解する効果(switchステートメントのブランチ)ではなく、人間が理解する機能(クラス)でコードを分離できます。非常に快適な「ボトムアップ」スタイルで記述します。しかし、私は彼らの柔軟性の主張に懐疑的です。

4
コマンドパターン設計
コマンドパターンのこの古い実装があります。これは、すべてのDIOperation実装を通じてContextを渡すようなものですが、後で学習と学習のプロセス(決して停止しない)で最適ではないことに気付きました。また、ここでの「訪問」は実際には合わず、混乱するだけだと思います。 また、コマンドは他のことについて何も知らず、現時点ではすべてが同じキーと値のペアを共有するため、コードのリファクタリングを考えています。どのクラスがどのKey-Valueを所有しているかを維持するのは非常に難しく、変数の重複につながる場合があります。 ユースケースの例:CommandBがCommandAによって設定されるUserNameを必要とするとしましょう。CommandAはキーUserNameForCommandB = Johnを設定する必要がありますか?または、共通のUserName = John Key-Value を共有する必要がありますか?UserNameが3番目のコマンドで使用されるとどうなりますか? この設計を改善するにはどうすればよいですか?ありがとう! class DIParameters { public: /** * Parameter setter. */ virtual void setParameter(std::string key, std::string value) = 0; /** * Parameter getter. */ virtual std::string getParameter(std::string key) const = 0; virtual ~DIParameters() = 0; }; class DIOperation { public: /** * …

5
抽象メソッドまたは仮想メソッドを使用する必要がありますか?
基本クラスが純粋なインターフェイスクラスであることが望ましくないと仮定し、以下の2つの例を使用すると、抽象メソッドまたは仮想メソッドクラス定義を使用する方が適切なアプローチですか? 「抽象」バージョンの利点は、見た目がきれいで、派生クラスに意味のある実装を強制的に提供させることです。 「仮想」バージョンの利点は、他のモジュールによって簡単に引き込められ、抽象バージョンが必要とするような基本的なフレームワークを追加することなくテストに使用できることです。 要約版: public abstract class AbstractVersion { public abstract ReturnType Method1(); public abstract ReturnType Method2(); . . public abstract ReturnType MethodN(); ////////////////////////////////////////////// // Other class implementation stuff is here ////////////////////////////////////////////// } 仮想バージョン: public class VirtualVersion { public virtual ReturnType Method1() { return ReturnType.NotImplemented; } public virtual ReturnType Method2() …
11 c#  design 

3
ビューモデルでのビジネスオブジェクトの使用
再利用可能なビジネスオブジェクトを使用する場合、ビューモデルを構築する際のベストプラクティスとは何ですか? 呼び出すオブジェクトを使用して、Builderビューモデルを構築します。ビューの各論理ユニット(オーダー、ユーザーなど)ごとに1つのビルダー。ここで、各ユニットにはさまざまなビューモデルを含めることができます(オーダーにはサマリー、オーダーラインなどが含まれます)。 ビルダーは、ビューモデルを構築するために、1つ以上の標準ビジネスオブジェクトを介してデータをプルする場合があります。 ビューモデルでビジネスオブジェクト/モデルを使用する場合のベストプラクティスとは何ですか? アプローチ1 ビューモデルでビジネスオブジェクトの使用を許可しますか? //Business object in some library public class Order { public int OrderNum; public int NumOrderLines; //... } //Order builder in website public class OrderBuilder { public OrderSummary BuildSummaryForOrder(int OrderNum) { Some.Business.Logic.Order obOrder = Some.Business.Logic.GetOrder(OrderNum); //Any exception handling, additional logic, or whatever OrderSummary obModel = …

3
try-catch-finallyブロックの無関係なコードは「どれほど悪い」ですか?
これは関連しているQ: 返品後の作業を行うためのfinally節の使用は、スタイルが悪い/危険ですか? 参照されるQでは、最終的に使用されるコードは、使用される構造とプリフェッチの必要性に関連しています。私の質問は少し異なりますが、より多くの聴衆にとって密接な関係があると思います。私の特定の例はC#winformアプリですが、これは最終的にC ++ / Javaの使用にも適用されます。 私は、ブロックに例外や例外処理/クリーンアップに関係のないコードがたくさんあるtry-catch-finallyブロックにかなり気付いています。そして、例外と処理に密接に関連するコードで非常にタイトなtry-catch-finallyブロックを作成するという私のバイアスを認めます。ここに私が見ているもののいくつかの例があります。 tryブロックには、スローされる可能性のあるコードに至るまでの多くの予備的な呼び出しと変数が設定されます。ロギング情報は、セットアップを取得し、tryブロックでも実行されます。 最後に、ブロックはform / module / controlのフォーマット呼び出し(catchブロックで表されるように、アプリが終了しようとしているにもかかわらず)を持ち、パネルなどの新しいオブジェクトを作成します。 大体: methodName(...) { 試してみる { //メソッドの多くのコード... //スローできるコード... //メソッドとリターンのためのより多くのコードを... } catch(何か) {//例外を処理する} 最後に { //例外によるいくつかのクリーンアップ、クローズ //作成されたもののためのより多くのコード(例外がスローされる可能性があることを無視)... //さらにオブジェクトを作成します } } コードは機能するため、何らかの価値があります。それはうまくカプセル化されておらず、ロジックは少し複雑です。私は(苦労して)コードを移動したりリファクタリングしたりするリスクに精通しているので、私の質問は、同様に構造化されたコードに関する他の人の経験を知りたいということになります。 悪いスタイルは変更を加えることを正当化しますか?同様の状況で誰かがひどくやけどをしたことがありますか?その悪い経験の詳細を共有してくれませんか?私が過剰に反応していて、スタイルがそれほど悪くないので、それを残してください?物事を片付けることのメンテナンスの利点を得る?

4
C ++の「インターフェース」という用語
Javaはとを明確に区別classしinterfaceます。(C#もそうだと思いますが、経験はありません)。ただし、C ++を記述するとき、クラスとインターフェイスの間に言語による強制的な区別はありません。 そのため、Javaには多重継承がないための回避策としてインターフェイスを常に見てきました。このような区別をすることは、C ++ではarbitrary意的で無意味に感じます。 私は常に「最も明白な方法で物事を書く」アプローチを採用する傾向がありました。そのため、C ++でJavaのインターフェースと呼ばれるものがある場合、例えば: class Foo { public: virtual void doStuff() = 0; ~Foo() = 0; }; そして、私Fooはおそらくほとんどの実装者が、おそらく私が書くだろういくつかの一般的な機能を共有したいと決めた。 class Foo { public: virtual void doStuff() = 0; ~Foo() {} protected: // If it needs this to do its thing: int internalHelperThing(int); // Or if it doesn't need the …

5
テスト可能なコードの作成と投機的一般性の回避
私は今朝いくつかのブログ投稿を読んでいて、これに出くわしました: Customerインターフェースを実装する唯一のクラスがCustomerImplである場合、実際には実行時に代用するものがないため、ポリモーフィズムと代替性はありません。それは偽の一般性です。 インターフェースを実装すると複雑さが増し、実装が1つしかない場合は、不必要な複雑さが加わると主張するかもしれません。必要以上に抽象的なコードを記述することは、「投機的一般性」と呼ばれるコードの匂いと見なされることがよくあります(投稿でも言及されています)。 しかし、TDDを使用している場合、インターフェイス実装または他のポリモーフィックオプションの形式であるかどうかにかかわらず、クラスを継承可能にし、そのメソッドを仮想にすることで、その投機的な一般性なしにテストダブルを作成することはできません。 それでは、このトレードオフをどのように調整するのでしょうか?テスト/ TDDを促進するために投機的に一般的であることは価値がありますか?テストdoubleを使用している場合、これらは2番目の実装としてカウントされ、一般性が推測されなくなりますか?具体的な協力者のモックを可能にする、よりヘビーなモックフレームワークを検討する必要があります(たとえば、C#の世界でのMolesとMoq)。または、具体的なクラスでテストし、デザインが自然にポリモーフィズムを必要とするときまで、「統合」テストと考えられるものを記述する必要がありますか? 私はこの問題に関する他の人々の見解を読んでみたいです-あなたの意見を事前に感謝します。

3
ScalaとLWJGLを使用した簡易ゲームの関数型プログラミングアプローチ
Javaの命令型プログラマであるIは、関数型プログラミングの設計原則(特に参照の透明性)に基づいて、スペースインベーダーの単純なバージョンを生成する方法を理解したいと考えています。しかし、デザインを考えようとするたびに、極端な可変性の泥沼で迷子になります。これは、関数型プログラミングの純粋主義者によって回避される同じ可変性です。 関数型プログラミングを学習する試みとして、LWJGLを使用してScalaで非常にシンプルな2DインタラクティブゲームであるSpace Invader(複数形の欠如に注意)を作成することにしました。基本的なゲームの要件は次のとおりです。 「A」キーと「D」キーでそれぞれ画面の下部にあるユーザーシップを左右に移動しました 発射間隔が0.5秒になるようにスペースバーで起動したユーザー船の弾丸を真っ直ぐ発射 射撃の間に0.5秒から1.5秒のランダムな時間で起動するエイリアン船の弾丸が真下に発射されました 元のゲームから意図的に除外されたものは、画面の上部にあるWxHエイリアン、分解可能な防御バリアx3、高速ソーサー船です。 さて、実際の問題領域に移りましょう。私にとって、決定論的な部分はすべて明らかです。アプローチ方法を検討する私の能力を妨げているのは、非決定的な部分です。決定論的な部分は、弾丸が存在する場合の弾道、エイリアンの連続的な動き、およびプレイヤーの船またはエイリアンのいずれか(または両方)の衝突による爆発です。(私にとって)非決定的な部分は、ユーザー入力のストリームを処理し、エイリアンの弾丸の発射を決定するためのランダムな値のフェッチを処理し、出力(グラフィックとサウンドの両方)を処理します。 私はこの種のゲーム開発を長年にわたって行うことができます(そして、これまでしてきました)。しかし、それはすべて命令型パラダイムからでした。さらに、LWJGLは、スペース侵略者の非常にシンプルなJavaバージョンを提供します(これは、セミコロンなしのJavaとしてScalaを使用してScalaに移行し始めました)。 Java / Imperativeプログラミングから来た人が理解する方法でアイデアを直接扱ったものはいないように思われる、この領域に関するいくつかのリンクを以下に示します。 純粋に機能的なレトロゲーム、パート1ジェームズハーグ 同様のスタックオーバーフローポスト Clojure / Lispゲーム スタックオーバーフローに関するHaskellゲーム Yampaの(Haskellでの)関数型リアクティブプログラミング Clojure / LispとHaskellのゲーム(ソース付き)にはいくつかのアイデアがあるようです。残念ながら、私は単純なJava命令型脳にとって意味のあるメンタルモデルにコードを読み取ったり解釈したりすることはできません。 FPが提供する可能性に非常に興奮しており、マルチスレッドのスケーラビリティ機能を味わうことができます。Space Invaderの時間+イベント+ランダム性モデルのような単純なものをどのように実装し、高度な数学的理論のように感じることなく、適切に設計されたシステムで決定論的部分と非決定論的部分を分離する方法を理解できたと思います; すなわちヤンパ、私は設定されるでしょう。単純なゲームの生成にYampaの理論レベルの学習が必要と思われる場合、必要なすべてのトレーニングと概念フレームワークを取得するためのオーバーヘッドが、FPの利点の理解を大きく上回ります(少なくともこの単純化された学習実験の場合) )。 フィードバック、提案されたモデル、問題領域へのアプローチ方法(ジェームズハーグがカバーしている一般性よりも具体的)をお勧めします。

6
単一責任の原則との闘い
この例を考えてみましょう: ウェブサイトを持っています。これにより、ユーザーは投稿(何でも可能)を作成し、投稿を説明するタグを追加できます。コードには、投稿とタグを表す2つのクラスがあります。これらのクラスをPostおよびと呼びましょうTag。 Post投稿の作成、投稿の削除、投稿の更新など Tagを処理します。タグの作成、タグの削除、タグの更新などを処理します。 欠落している操作が1つあります。タグと投稿のリンク。私は誰がこの手術をすべきかと格闘しています。どちらのクラスにも等しく適合する可能性があります。 一方では、PostクラスにTagaをパラメーターとして受け取り、タグのリストに格納する関数を含めることができます。一方、Tagクラスが取る関数可能性がありPost、パラメータとして及びリンクTagにしますPost。 上記は私の問題の一例です。私は実際には、すべて類似した複数のクラスでこれに直面しています。それは両方に等しく適合する可能性があります。実際に両方のクラスに機能を配置するのではなく、この問題を解決するのに役立つ規則やデザインスタイルが存在します。私は1つを選ぶだけでは足りないものがあるはずだと思いますか? たぶん両方のクラスに入れるのが正しい答えでしょうか?

8
アジャイルやXPなどの進化的手法で設計の行き詰まりに陥った場合はどうしますか?
Martin Fowlerの有名なブログ記事Is Design Deadを読んでいたとき 、私が得た印象的な印象の1つは、アジャイル方法論とエクストリームプログラミングでは、デザインとプログラミングが進化的であるという事実を考えれば、物事をリファクタリングする必要がある点が常にあるということです。 プログラマーのレベルが高く、設計の意味を理解し、重大な間違いを犯さない場合、コードは進化し続ける可能性があります。しかし、通常の状況では、この状況での地上の現実は何ですか? ある重要な開発が製品に組み込まれている通常の日には、要件に重大な変更が生じた場合、それがどれだけ望むかという制約ではないので、基本的な設計の側面を変更することはできませんか?(コードの大部分を捨てずに)。設計と要件のさらなる可能な改善で行き止まりに達する可能性は非常に低いですか? ここではアジャイル以外のプラクティスを提唱していませんが、実際の経験に関しては、アジャイル、反復、または進化の開発方法を実践している人々から知りたいです。 あなたはそのような行き止まりに達したことがありますか?どうやってそれを避けたり、逃れたりできましたか?または、デザインが進化してもクリーンで柔軟なままであることを保証する手段はありますか?
11 design  agile 

1
描画スレッドの相互作用
UML(-like)表記でスレッドの相互作用(ペンと鉛筆)を描きたいです。私はUMLを主張しません。読者に明らかなことはすべきです。 私はシーケンス図から始めましたが、これが最善の方法だとは思いません。常に、画面外から来る「アクションイニシエーター」が存在し、SSDのアイデアを壊します。それぞれがステートマシンを所有する9〜10個のスレッドを持つ中規模のコードベースを継承し、その仕組みを理解しようとしています。 スレッドの相互作用を視覚化するにはどうすればよいですか?

2
分析と設計との違いは何ですか?
「アナライザーが必要」または「デザイナーが必要」というマネージャーの声を聞いたことがあると思います。私は.NET開発者ですが、アナライザーをデザイナー(WebデザイナーやUIデザイナーではない)と区別することはほとんどできません。 アナライザーは誰ですか?デザイナーは誰ですか?それらは重なりますか?

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