ソフトウェア工学

システム開発ライフサイクル内で働く専門家、学者、学生向けのQ&A

8
すべての列挙型を1つのファイルに含め、複数のクラスで使用するのは悪い習慣ですか?
私は意欲的なゲーム開発者であり、時折インディーゲームに取り組んでいます。しばらくの間、最初は悪い習慣のように思われたことをしていましたが、ここで経験豊富なプログラマーから答えをもらいたいです。 enumList.hゲームで使用するすべての列挙型を宣言するファイルがあります。 // enumList.h enum materials_t { WOOD, STONE, ETC }; enum entity_t { PLAYER, MONSTER }; enum map_t { 2D, 3D }; // and so on. // Tile.h #include "enumList.h" #include <vector> class tile { // stuff }; 主なアイデアは、1つのファイルでゲーム内のすべての列挙型を宣言し、使用する必要があるファイルで宣言するのではなく、特定の列挙型を使用する必要があるときにそのファイルをインポートすることです。これは、物事をきれいにするためです。1つの列挙にアクセスするためだけにページを開くのではなく、1か所ですべての列挙にアクセスできます。 これは悪い習慣ですか、何らかの形でパフォーマンスに影響を与えることができますか?


3
ORMレイヤー上に抽象化レイヤーを作成する
リポジトリにORMを使用している場合、データベースからすでに十分に抽象化されていると思います。 ただし、私が現在働いているところでは、後でORMを変更したい場合に備えて、ORMを抽象化するレイヤーが必要だと誰かが信じています。 多くのORMで機能するレイヤーを作成するのは本当に必要なのでしょうか、それとも単純に頭がかかりますか? 編集 より詳細に説明するために: AutoMapperでマップされるPOCOクラスとEntityクラスがあります。エンティティクラスは、リポジトリレイヤーによって使用されます。リポジトリレイヤーは、追加の抽象化レイヤーを使用して、Entity Frameworkと通信します。 ビジネスレイヤーは、Entity Frameworkに直接アクセスできません。ORM上の抽象化の追加レイヤーがなくても、これはリポジトリレイヤーを使用するサービスレイヤーを使用する必要があります。どちらの場合も、ビジネスレイヤーはORMから完全に分離されています。 主な議論は、将来ORMを変更できるようにすることです。リポジトリレイヤー内に実際にローカライズされているため、私にとっては既に十分に分離されており、「品質」コードを得るために抽象化の追加レイヤーが必要な理由はわかりません。
12 database  orm 

7
リファクタリングとオープン/クローズの原則
最近、きれいなコード開発に関するWebサイトを読んでいます(英語ではないため、ここにはリンクを入れません)。 このサイトで宣伝されている原則の1つは、オープンクローズド原則です。各ソフトウェアコンポーネントは、拡張用にオープンにし、変更用にクローズする必要があります。たとえば、クラスを実装してテストした場合、バグを修正するか、新しい機能を追加する(たとえば、既存のメソッドに影響を与えない新しいメソッド)ためにクラスを変更するだけです。既存の機能と実装は変更しないでください。 通常、インターフェイスIと対応する実装クラスを定義することにより、この原則を適用しますA。クラスAが安定(実装およびテスト)になったとき、通常はあまり変更しません(おそらく、まったく変更しません)。 コードに大きな変更を必要とする新しい要件(パフォーマンス、インターフェイスのまったく新しい実装など)が到着した場合、新しい実装を作成し、成熟していない限りB使用Aし続けBます。B成熟したときに必要なのは、Iインスタンス化の方法を変更することだけです。 新しい要件がインターフェースの変更も示唆している場合、新しいインターフェースI'と新しい実装を定義しますA'。ですからI、A凍結しており、残る実装限りとして生産システムのためI'およびA'それらを交換するのに十分安定していません。 そのため、これらの観察を考慮して、Webページが複雑なリファクタリングの使用を提案していることに少し驚いていました。 オープン/クローズド原則の実施と、ベストプラクティスとしての複雑なリファクタリングの使用の提案との間に矛盾や矛盾はありませんか?または、ここでのアイデアは、クラスの開発中に複雑なリファクタリングを使用できるということですAが、そのクラスが正常にテストされたら、凍結する必要がありますか?

9
コピーアンドペーストされたテストコード:これはどれほど悪いですか?
私の現在の仕事は、主に私たちが取り組んでいるさまざまなアプリケーションのGUIテストコードを書くことです。ただし、テスト内で多くのコードをコピーして貼り付ける傾向があることがわかりました。この理由は、テストしている領域は、繰り返しが必要なほど似ている傾向があるが、コードをメソッドまたはオブジェクトにカプセル化するほど似ていない傾向があるためです。クラスやメソッドをより広範囲に使用しようとすると、テストの保守が面倒になり、最初から書くのが完全に難しくなることがあります。 代わりに、通常、あるセクションからテストコードの大きな部分をコピーして別のセクションに貼り付け、必要な小さな変更を加えます。オブジェクト指向の原則や関数を使用するなど、構造化されたコーディング方法は使用しません。 テストコードを書くとき、他のコーダーはこのように感じますか?DRYとYAGNIの原則に従うことは明らかですが、テストコード(とにかくGUIテスト用の自動化されたテストコード)を使用すると、これらの原則に従うことが難しくなることがわかります。または、より多くのコーディングの練習とより良い全体的なシステムが必要ですか? 編集:私が使用しているツールはSilkTestで、4Testと呼ばれる独自の言語です。同様に、これらのテストは主にWindowsデスクトップアプリケーション用ですが、このセットアップを使用してWebアプリもテストしました。

2
コンパイル済みのC ++ 11ライブラリ(lib、dllなど)を古いC ++コンパイラにリンクできますか?
古いC ++コンパイラ(VS2008やgcc3.4など)は、C ++ 11で記述された外部ライブラリとリンクできますか? 私の考えでは、C ++ 11 .libファイルはこの段階では単なるバイトコードであり、何らかの方法で解決可能かつ呼び出し可能であれば、古いコンパイラの生成方法を気にするべきではありません。 私はAPIがまだC ++ 03ユーザーをサポートする小さなライブラリを開発しています。だから、楽しみにして、std::unique_ptrなどの便利な機能を使用してライブラリを実装しても大丈夫なのか、それとも固執する必要があるのboost::でしょうか?
12 c++  c++11 

3
クラス内の属性を事前に初期化することをお勧めしますか、それとも途中で追加することですか?
これが絶対に二日酔いの質問である場合は申し訳ありませんが、ベストプラクティスがどこにあるのか興味があり、Googleで良い答えを見つけることができないようです。 Pythonでは、通常、空のクラスをスーパーキャッチオールデータ構造コンテナー(JSONファイルのようなもの)として使用し、途中で属性を追加します。 class DataObj: "Catch-all data object" def __init__(self): pass def processData(inputs): data = DataObj() data.a = 1 data.b = "sym" data.c = [2,5,2,1] これにより、コンテナオブジェクトは基本的に何でも保存できるため、非常に大きな柔軟性が得られます。したがって、新しい要件が生じた場合は、DataObjオブジェクトに別の属性として追加します(コードで渡します)。 しかし、最近、コードの読み取りが非常に難しくなるため、これはひどい慣行であると私(FPプログラマー)に感銘を受けました。すべてのコードを調べて、DataObjが実際に持っている属性を把握する必要があります。 質問:柔軟性を犠牲にすることなく保守性を高めるために、これをどのように書き直すことができますか? 関数型プログラミングから採用できるアイデアはありますか? 私はそこにベストプラクティスを探しています。 注:1つの考えは、遭遇することが予想されるすべての属性でクラスを事前初期化することです。例えば class DataObj: "Catch-all data object" def __init__(self): data.a = 0 data.b = "" data.c = [] def processData(inputs): data = …

2
一部のNOPコードは他とは異なる方法で処理されますか?
私はこれに興味があります、私が持っているとしましょう: 00000000001 90 nop 00000000002 90 nop 00000000003 90 nop これとまったく同じように実行されますか? 00000000001 0F1F00 nop dword [ds:rax] 2番目の例は、最初の例に対してどのような効果がありますか?
12 assembly 

8
開発者がタイムリーにコードレビューを行えるようにする方法
私が働いている会社では、コミットする前にすべてのコードを他の開発者がレビューする必要があります。私のチームのメンバーは、他の開発者がコーディングに忙しすぎてレビューを行うことができないため、特に非常に長い場合、しばしばイライラします。他の開発者にタイムリーなコードレビューを行うためのインセンティブをどのように与えますか? (私たちはgit-svnを使用しているので、レビューを待っている間もコーディングを続けることができます。しかし、コードをコミットする前に長い時間待たなければならない場合は、いらいらします。)

2
CQRS +イベントソーシング:(それは正しいですか)コマンドは一般にポイントツーポイントで通信されますが、ドメインイベントはpub / subを介して通信されますか?
私は基本的に、CQRSの概念と関連する概念に頭を包み込もうとしています。 CQRSには必ずしもメッセージングとイベントソーシングが組み込まれているわけではありませんが、適切な組み合わせのようです(これらの概念を組み合わせた多くの例/ブログ投稿でわかるように) 何かの状態変更のユースケース(SOに関する質問を更新するなど)が与えられた場合、次のフローが正しいと考えますか(ベストプラクティスとして)。 システムは、いくつかの小さなコマンドに分割される可能性のある集約UpdateQuestionCommandを発行します。質問集約ルートをターゲットとするUpdateQuestion、およびユーザー集約ルートをターゲットとするUpdateUserAction(ポイントをカウントするなど)。これらは、ポイントツーポイントメッセージングを使用して非同期的に送信されます。 集約ルートはそれぞれの処理を実行し、すべてがうまくいけば、QuestionUpdatedイベントとUserActionUpdatedイベントをそれぞれ起動します。これらのイベントには、イベントストアに外部委託された状態が含まれます。 これらのイベントは、ブロードキャスト用のpub / subキューにも置かれます。サブスクライバー(読み取りビューを作成する1つまたは複数のプロジェクターの可能性が高い)は、これらのイベントを無料でサブスクライブできます。 一般的な質問:コマンドはPoint-to-Pointで通信される(つまり、受信者が既知である)のに対して、イベントはブロードキャストされる(つまり、受信者が不明である)ことは本当にベストプラクティスですか? 上記を仮定すると、ポイントツーポイントではなくpub / subを介してコマンドをブロードキャストすることの利点/欠点は何でしょうか? 例:佐賀はどの集約ルートが最初に参加するのかわからないため、集約ルートの1つに障害が発生した場合に佐賀が果たす必要がある調停の役割が妨げられるため、佐賀の使用中にコマンドをブロードキャストすることが問題になる可能性があります。 一方、コマンドのブロードキャストが許可されると、利点(柔軟性)が得られます。

2
Unicode文字列の効率的なTrie実装
効率的な文字列トライの実装を探しています。ほとんどの場合、次のようなコードが見つかりました。 Javaでの参照実装(ウィキペディアごと) これらの実装は、主に2つの理由で嫌いです。 256文字のASCII文字のみをサポートします。キリル文字などをカバーする必要があります。 それらは非常にメモリ効率が悪いです。 各ノードには、256個の参照の配列が含まれます。これは、Javaの64ビットマシンでは4096バイトです。これらの各ノードは、それぞれ4096バイトの参照を持つ最大256個のサブノードを持つことができます。したがって、すべてのASCII 2文字列の完全なトライには1MBを少し超えるサイズが必要です。3つの文字列?ノード内の配列にのみ256MB。等々。 もちろん、トライに1600万の3文字列すべてを含めるつもりはないので、多くのスペースが無駄になっています。これらの配列のほとんどは、挿入されたキーの実際の数をはるかに超える容量があるため、単なるヌル参照です。また、Unicodeを追加すると、配列はさらに大きくなります(charの値はJavaの256ではなく64kです)。 文字列の効率的なトライを作成する希望はありますか?これらのタイプの実装に対するいくつかの改善を検討しました。 参照の配列を使用する代わりに、プリミティブ整数型の配列を使用できます。これは、サイズが実際のノードの数に近いノードへの参照の配列にインデックスを付けます。 深いツリーを犠牲にしてサイズ16のノード配列を可能にする4ビットの部分に文字列を分割できます。
12 unicode  trie 

1
大きなオブジェクト階層での訪問者パターンの使用
環境 オブジェクトの階層(式ツリー)で「疑似」ビジターパターン(二重ディスパッチを使用しないように疑似)を使用しています。 public interface MyInterface { void Accept(SomeClass operationClass); } public class MyImpl : MyInterface { public void Accept(SomeClass operationClass) { operationClass.DoSomething(); operationClass.DoSomethingElse(); // ... and so on ... } } ただし、MyInterfaceの実装の数は非常に多く(〜50以上)、余分な操作を追加する必要がないため、この設計は疑わしく、かなり快適でした。 各実装は一意であり(異なる式または演算子です)、一部は複合(つまり、他の演算子/リーフノードを含む演算子ノード)です。 トラバーサルは現在、ツリーのルートノードでAccept操作を呼び出すことによって実行され、その操作は、その子ノードのそれぞれでAcceptを呼び出します。 しかし、きれいな印刷などの新しい操作を追加する必要があるときが来ました。 public class MyImpl : MyInterface { // Property does not come from MyInterface public string …


4
1つはC ++とWebをどのようにインターフェースしますか(たとえばGoogleで)?
グーグルは、長年コーディングしてきた途方もない量のC ++で有名です。間違っている場合は修正してください。ただし、Googleの主要な検索エンジンの大部分はC ++で作成されています。C ++で書かれたプログラムをどのように取り、Webサイトとインターフェイスさせるのですか? 注:私は、特にGoogleがこれを行う方法を探しているのではなく、一般的にどのように行われるかを探しています。

3
メインメソッドは、オブジェクトの作成とメソッド呼び出しのみで構成する必要がありますか?
私の友人から、ベストプラクティスは、mainメソッドを含むクラスには名前を付けMain、mainメソッドのみを含めることがベストプラクティスだと言われました。また、mainメソッドは入力のみを解析し、他のオブジェクトを作成し、他のメソッドを呼び出す必要があります。Mainクラスとmainメソッドは、何かをやるべきではありません。基本的に、彼はmainメソッドを含むクラスは次のようにすべきだと言っています: public class Main { public static void main(String[] args) { //parse inputs //create other objects //call methods } } ベストプラクティスですか?

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