ソフトウェア工学

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

5
RESTとHATEOASはWebサービスに適したアーキテクチャですか?
正しく理解できれば、RESTはWebのアーキテクチャの記述モデルとしてRoy Fieldingによって正式化されました。AFAIK FieldingはRESTが良いと主張したわけではなく、Webの事実上のアーキテクチャを説明しているだけでした。Webはこの時点ですでに非常に成功した分散ハイパーテキストシステムを証明しているため、この種のRESTは、主に人間がナビゲートして消費する分散ハイパーメディアのドメインの成功したアーキテクチャとして検証されます。 REST Webサービスは、RESTアーキテクチャをAPIに適用することで作成されました。しかし、実際にはRESTがこのドメインに望ましいアーキテクチャであると考える理由はありますか?より具体的には、HATEOASがマシンツーマシン通信の有益な設計原則であるという証拠はありますか? 私の懸念は、よく知られているコンテンツタイプ(HTML、画像、ビデオなど)がほとんどなく、クライアントがそれらを使用する方法を知っているため、HATEOASはハイパーメディアに意味があることです。ただし、APIの場合、コンテンツタイプは非常に具体的であり、クライアントがそれらを消費するように特別にプログラムされている場合にのみ、クライアントが意味のある方法で消費できます。クライアントにURLを返すだけでは、クライアントは指定されたリソースを消費できません。
15 rest  hateoas 

2
マイクロソフトは、C#での 'var'の使用を推奨していませんか?(VS2017)
私は来たるVisual Studio 2017を見ています。 Boosted Productivityというタイトルのセクションの下に、すべてのvarの出現を明示的な型に置き換えるために使用されているVisual Studioのイメージがあります。 このコードには、Visual Studioが「修正が必要」と特定したいくつかの問題があるようです。 C#でのvarの使用に関する理解を再確認したかったので、Eric Lippertによる2011年の暗黙的な型指定の使用と誤用に関する記事を読みました。 エリック言う: 必要な場合はvarを使用します。匿名型を使用している場合。 宣言のタイプが初期化子から明らかな場合、特にオブジェクト作成の場合は、varを使用します。これにより、冗長性がなくなります。 コードが変数のセマンティック「ビジネス目的」を強調し、そのストレージの「機械的」詳細を軽視する場合は、varの使用を検討してください。 コードを正しく理解して維持するために必要な場合は、明示的な型を使用します。 「var」を使用するかどうかに関係なく、説明的な変数名を使用します。変数名は、ストレージの詳細ではなく、変数のセマンティクスを表す必要があります。「decimalRate」は悪いです。「interestRate」は良いです。 コードでのvarの使用のほとんどはおそらく大丈夫だと思います。読み取るビットにvarを使用しないでよいと思います... var tweetReady = workouts [ ... ] ...多分、それが何であるかが100%すぐにわかるわけではないかもしれませんが、それでも私はそれがaであることをかなり早く知っていbooleanます。 この部分の変数の使用... var listOfTweets = new List<string>(); ... varの適切な使用方法とまったく同じように見えます。なぜなら、次のことを行うのは冗長だと思うからです List<string> listOfTweets = new List<string>(); Ericが言ったことに基づいていますが、変数はおそらくlistOfTweetsではなくツイートでなければなりません。 varここですべての使用を変更する理由は何でしょうか?このコードに何か間違っていることがありますか?

5
Cでインターフェイス分離の原則を適用する方法は?
「M」と言うモジュールがあり、「C1」、「C2」、「C3」と言うクライアントがいくつかあります。モジュールMの名前空間、つまり、それが公開するAPIとデータの宣言を、次のような方法でヘッダーファイルに割り当てます。 どのクライアントでも、必要なデータとAPIのみが表示されます。モジュールの残りの名前空間はクライアントから隠されています。つまり、インターフェース分離の原則に準拠しています。 宣言は複数のヘッダーファイルで繰り返されません。つまり、DRYに違反しません。 モジュールMは、クライアントに依存しません。 クライアントは、モジュールMで使用されていない部分で行われた変更の影響を受けません。 既存のクライアントは、追加のクライアント(または削除)の影響を受けません。 現在、クライアントの要件に応じてモジュールの名前空間を分割することでこれに対処しています。たとえば、下の画像では、3つのクライアントに必要なモジュールの名前空間のさまざまな部分が示されています。クライアントの要件は重複しています。モジュールの名前空間は、「a」、「1」、「2」、「3」の 4つの独立したヘッダーファイルに分割されます。 ただし、これは前述の要件の一部、つまりR3およびR5に違反します。このパーティション化はクライアントの性質に依存するため、要件3に違反しています。また、新規クライアントの追加のモジュールの名前空間は、現在7つのヘッダファイルに分割して、新しいクライアントの追加と同様に、上記の画像の右側に見ることができ、このパーティションの変更および要件5.に違反し、 - 「 '、' b '、' c '、' 1 '、' 2 * '、' 3 * 'および' 4 '。ヘッダーファイルは2つの古いクライアントの変更を意味し、それにより再構築がトリガーされます。 Cのインターフェイス分離を非自発的な方法で実現する方法はありますか? はいの場合、上記の例をどのように扱いますか? 私が想像する非現実的な仮想ソリューションは次のようになります- モジュールには、名前空間全体をカバーする1つの太いヘッダーファイルがあります。このヘッダーファイルは、ウィキペディアページのようなアドレス可能なセクションとサブセクションに分かれています。各クライアントには、特定のヘッダーファイルが用意されています。クライアント固有のヘッダーファイルは、ファットヘッダーファイルのセクション/サブセクションへのハイパーリンクの単なるリストです。また、ビルドシステムは、モジュールのヘッダーでポイントするセクションのいずれかが変更された場合、クライアント固有のヘッダーファイルを「変更された」ものとして認識する必要があります。
15 c  interfaces  solid 

3
きれいなコード:パラメーターが少ない短いメソッドの結果
最近、コードのレビュー中に、新しい同僚が書いたコードに出会いました。これには匂いのあるパターンが含まれています。同僚の決定は、有名なClean Codeの本(およびおそらく他の同様の本)によって提案されたルールに基づいていると思います。 クラスコンストラクターは有効なオブジェクトの作成に完全に責任があり、その主なタスクはオブジェクトの(プライベート)プロパティの割り当てであることを理解しています。もちろん、オプションのプロパティ値がクラスコンストラクター以外のメソッドによって設定される可能性がありますが、そのような状況はかなりまれです(クラスの残りの部分がそのようなプロパティのオプション性を考慮する場合は、必ずしも間違っているわけではありません)。これは、オブジェクトが常に有効な状態であることを保証できるため、重要です。 しかし、私が遭遇したコードでは、ほとんどのプロパティ値は実際にはコンストラクター以外のメソッドによって設定されています。計算の結果の値は、クラス全体のいくつかのプライベートメソッド内で使用されるプロパティに割り当てられます。著者は、クラスプロパティを、それらを必要とする関数にパラメーター化するのではなく、クラス全体でアクセスできるグローバル変数であるかのように使用しているようです。さらに、クラスのメソッドは特定の順序で呼び出す必要があります。そうしないと、クラスはそれほど多くのことをしないからです。 このコードは、大きなパラメーターリスト(<3パラメーター)を回避するために、メソッドを短くする(<= 5行のコード)アドバイスにインスパイアされており、コンストラクターが機能しないようにする必要がある(何らかの計算を実行するなど)これはオブジェクトの有効性にとって不可欠です)。 もちろん、メソッドが特定の順序で呼び出されない場合に、あらゆる種類の未定義エラーが発生する可能性があることを証明できれば、もちろんこのパターンに反論することができます。ただし、これに対する応答では、プロパティの設定が必要なメソッドが呼び出されたらプロパティを設定する必要があることを検証する検証が追加されると予測しています。 ただし、特定の順序で(手続き的に)呼び出される一連のメソッドではなく、クラスが実際のオブジェクトの青写真になるように、コードを完全に変更することをお勧めします。 私が遭遇したコードは臭いを感じます。実際、クラスプロパティに値を保存するタイミングと、使用する別のメソッドのパラメーターに値を配置するタイミングについては、かなり明確な違いがあると思います。 。この区別の言葉を探しています。

2
ジェネリックは最新のコンパイラにどのように実装されていますか?
ここで私が意味しているのは、テンプレートからT add(T a, T b) ...生成されたコードにどのように行くかということです。これを実現するいくつかの方法を考えました。汎用関数をAST Function_Nodeに格納し、それを使用するたびに、元の関数ノードに、すべてのT型が使用されています。例えばadd<int>(5, 6)のための一般的な機能のコピーを保存するaddと、すべてのタイプに置き換えてT コピーで持ちますint。 したがって、次のようになります。 struct Function_Node { std::string name; // etc. Type return_type; std::vector<std::pair<Type, std::string>> arguments; std::vector<Function_Node> copies; }; 次に、これらのコードを生成しFunction_Node、コピーの場所リストにアクセスすると、すべてのコピーcopies.size() > 0で呼び出しますvisitFunction。 visitFunction(Function_Node& node) { if (node.copies.size() > 0) { for (auto& node : nodes.copies) { visitFunction(node); } // it's a generic function so …

5
マイクロサービスおよび消費者向けの承認および認証システム
会社のシステムをマイクロサービスベースのシステムにリファクタリングする予定です。このマイクロサービスは、社内の社内アプリケーションと、必要に応じてサードパーティパートナーによって使用されます。予約用、製品用など ロールとスコープをどのように処理するかは不明です。管理者、エージェント、エンドユーザーなどの3つの基本的なユーザーロールを作成し、必要に応じてコンシューマーアプリがスコープを微調整できるようにするという考え方です。 管理者は、デフォルトで(会社の)すべてのリソースを作成、更新、読み取り、削除できます。 エージェントは、会社のデータを作成、更新、および読み取ることができます。 エンドユーザーはデータを作成、更新、削除、および読み取ることができますが、エージェントまたは管理者と同じエンドポイントにアクセスすることはできません。また、エージェントや管理者と同じレベルではなく、データを作成または変更することもできます。たとえば、エンドユーザーはアカウント情報を更新または読み取ることができます。これは、エージェントができるようになりますが、管理者ノートを表示または更新することはできません。 デフォルトでは、エージェントは会社の各リソースを作成、読み取り、更新でき、それはトークン/セッションに要求できる最大スコープですが、クライアント(APIコンシューマー)アプリケーションの開発者は、エージェントの1人が特定のリソースのみを読み取り、作成します。 内部セキュリティでこれを処理し、データベースにデータを書き込むようにするか、クライアントにスコープを小さくしてトークンを要求することで内部的に処理させ、どのエージェントがデータベースにどのスコープを持つかを書き込むようにすることをお勧めします?この方法では、トークンスコープのみを追跡する必要があります。 この欠点は、チームが内部アプリケーションで微調整されたアクセスメカニズムを作成する必要があることです。 この考え方では、マイクロサービスとその承認システムはクライアントのニーズに煩わされるべきではありません。なぜなら、それらは消費者であり、システムの一部ではないからです。 この委任は良いアプローチですか?

1
汎用C ++ラッパーを使用してRustの所有権モデルを実現できますか?
Rustの並行処理の安全性に関するこの記事をご覧ください。 http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html これらのアイデアのどれだけがC ++ 11(またはそれ以降)で達成できるのかと思っていました。特に、所有権を渡すメソッドに所有権を譲渡する所有者クラスを作成できますか?C ++には変数を渡す方法がたくさんあるので不可能だと思われますが、クラスまたはテンプレートにいくつかの制限を設けて、メソッドのパスごとにテンプレートコードが実行されるようにすることができますか?

5
厳密なTDDとDDDを組み合わせる方法
TDDは、テストによって導かれるコードの設計に関するものです。 したがって、通常、典型的なレイヤーは事前に構築されていません。それらはリファクタリング手順でわずかに表示されるはずです。 ドメイン駆動型設計には、アプリケーション層、インフラストラクチャ層、ドメイン層、永続層などの十分に確立された層を定義する多くの技術的パターンが含まれます。 DDDプロジェクトのコーディング部分をゼロから開始するには、どのように動作するのですか? DDDの技術的なパターンに適合するために、設計をテストから厳密に浮かび上がらせる必要がありますか? または、それらの空のレイヤー(アプリケーション、エンティティ/ドメインサービス、インフラストラクチャ)を作成し、TDDをそれぞれに個別に適合させる必要があります(モックを使用してレイヤー間を分離します)。

2
データ検証:分離されたクラスかどうか
検証が必要なデータが大量にある場合、検証のみを目的として新しいクラスを作成する必要がありますか、またはメソッド内検証に固執する必要がありますか? 私の特定の例では、トーナメントやイベント/カテゴリクラス企図:TournamentとEvent、モデルのスポーツ大会や各トーナメントは、1つのまたは多数のカテゴリがあります。 これらのクラスで検証するすべての種類のものがあります:プレイヤーは空である必要があり、一意である必要があり、各プレイヤーがプレイするマッチの数、各マッチが持っているプレイヤーの数、事前に定義されたマッチアップ、およびはるかに大きいなど複雑なルール。 また、クラスを相互に統合する方法など、全体として検証する必要のある部分もあります。たとえば、aのユニタリ検証はPlayer問題なく実行できますが、イベントに同じプレーヤーが2回ある場合、検証エラーになります。 では、これはどうですか?:モデルクラスのセッターや同様のメソッドを使用してデータを追加するときの事前チェックを絶対に忘れて、代わりに検証クラスにそれを処理させます。 だから我々は、のようなものがありますEventValidatorとのEventメンバーとして、そしてvalidate()すべてのメンバーのルールを検証するために、オブジェクト全体を検証する方法に加え、特異な方法を。 次に、有効なオブジェクトをインスタンス化する前に、無効な値を防ぐために検証を実行します。 私の設計は正しいですか?私は何か違うことをすべきですか? また、検証メソッドを返すブール値を使用する必要がありますか?または、検証が失敗した場合に例外をスローしますか?私にとって最良のオプションは、メソッドを返すブール値であり、オブジェクトがインスタンス化されたときに例外をスローすることです、例えば: public Event() { EventValidator eventValidator = new EventValidator(this); if (!eventValidator.validate()) { // show error messages with methods defined in the validator throw new Exception(); // what type of exception would be best? should I create custom ones? } }
15 java  design  data  validation 

2
DDD CQRS-クエリごとおよびコマンドごとの承認
概要 CQRS / DDDの承認は、コマンド/クエリごとに実装する必要がありますか? 多かれ少なかれ厳密にDDD CQRSパターンを使用するオンラインアプリケーションを初めて開発しています。私はいくつかの問題にぶつかりましたが、それを本当に回避することはできません。 私が作成しているアプリケーションは、元帳アプリケーションで、元帳を作成できるほか、従業員など他の人が元帳を表示/編集/削除できます。元帳の作成者は、作成した元帳のアクセス権を編集できる必要があります。所有権を変更することさえできます。ドメインには、TLedgerとTUserの 2つの集約があります。 セキュリティ、認可などに関するDDD / CQRSキーワードを含む多くの投稿を読みました。それらのほとんどは、セキュリティアプリケーションを構築していない限り、認可はGeneric Subdomainであると述べました。 この場合、コアドメインは確かに、トランザクション、バランシング、アカウントに関心のあるアカウンティングドメインです。ただし、元帳へのきめ細かいアクセスを管理できる機能も必要です。これをDDD / CQRSの用語でどのように設計するのか疑問に思っています。 コマンドがユビキタス言語の一部であるということは、DDDチュートリアルの至る所で述べられています。それらは意味があります。それらは「本物」を表す具体的なアクションです。 これらのコマンドとクエリはすべて、ユーザーが「実際に」実行する実際のアクションであるため、承認の実装をこれらすべての「コマンド」および「クエリ」と組み合わせる必要がありますか?ユーザーには、たとえばTLedger.addTransaction()を実行する権限がありますが、TLedger.removeTransaction()は実行できません。または、ユーザーはクエリ「getSummaries()」を実行できますが、「getTransactions()」は実行できません。 アクセス権を決定するために、user-ledger-commandまたはuser-ledger-queryの形式で3次元マッピングが存在します。 または、切り離された方法で、「permissions」という名前がユーザーに登録されます。特定のコマンド用にマップされる許可。たとえば、権限「ManageTransactions」では、ユーザーは「AddTransaction()」、「RemoveTransaction()」などを実行できます。 権限マッピングユーザー->元帳->コマンド/クエリ パーミッションマッピングユーザー->元帳->パーミッション->コマンド/クエリ それが質問の最初の部分です。または、簡単に言えば、CQRS / DDDの承認はコマンドごとまたはクエリごとに実装する必要がありますか?または、許可をコマンドから分離する必要がありますか? 第二に、許可に基づいた認可について。ユーザーは、自分の元帳または管理が許可されている元帳の権限を管理できる必要があります。 元帳で許可管理コマンドが発生する grantPermission()、revokePermission()などのイベント/コマンド/ハンドラーをLedger集計に追加することを考えました。この場合、これらのルールの強制はコマンドハンドラーで発生します。ただし、これにはすべてのコマンドに、そのコマンドを発行したユーザーのIDを含める必要があります。次に、そのコマンドを実行する権限がそのユーザーに存在する場合、TLedgerをチェックインします。 例えば ​​: class TLedger{ function addTransactionCmdHandler(cmd){ if (!this.permissions.exist(user, 'addTransaction') throw new Error('Not Authorized'); } } ユーザーの許可管理コマンド もう1つの方法は、TUserにアクセス許可を含めることです。TUserには一連の権限があります。次に、TLedgerコマンドハンドラーでユーザーを取得し、コマンドを実行する権限があるかどうかを確認します。しかし、これには、すべてのTLedgerコマンドのTUser集計を取得する必要があります。 class TAddTransactionCmdHandler(cmd) { this.userRepository.find(cmd.userId) .then(function(user){ if …

3
ループ内で変数を定義するのは良いですか?[閉まっている]
閉じた。この質問には、詳細または明確さが必要です。現在、回答を受け付けていません。 この質問を改善したいですか?詳細を追加し、この投稿を編集して問題を明確にします。 4年前に閉鎖されました。 私のインストラクターはかつて、ループ内で変数を定義するべきではないと教えてくれましたが、正直なところまだ理由がわかりません。 その欠点は何ですか? 体はそれを私に説明できますか?

4
マイクロサービスRESTまたはAMQP、どちらの場合
マイクロサービスアーキテクチャに関する多くの記事を読みましたが、AMQPまたはRESTをいつ使用すべきか疑問に思いました。 サービス間の疎結合は良いことであり、その場合AMQPが良い選択であるように思えます。しかし、AMQPを使用する場合、これはRESTエンドポイントが不要になることを意味します(ただし、HATEOASコンセプトが失われることを意味します)。 しかし、RESTは本当に私のサービスを構築するのに良い方法ですか?原因エンドポイントを使用しません...この場合、一方が他方より優れていますか? いつどちらを使用すればよいですか?

4
データリーダー行を取得し、すべてのレコードを読み取らない場合、データベース接続は閉じられますか?
方法を理解しながらyieldキーワード作品を、私が出会ったリンク1とリンク2の使用を提唱StackOverflowの上yield returnDataReaderオブジェクトを反復処理しながら、をし、それは私のニーズに合ったとしても。しかし、yield return以下に示すように使用し、DataReader全体を反復処理しない場合、DB接続はいつまでも開いたままになるのか、疑問に思います。 IEnumerable<IDataRecord> GetRecords() { SqlConnection myConnection = new SqlConnection(@"..."); SqlCommand myCommand = new SqlCommand(@"...", myConnection); myCommand.CommandType = System.Data.CommandType.Text; myConnection.Open(); myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection); try { while (myReader.Read()) { yield return myReader; } } finally { myReader.Close(); } } void AnotherMethod() { foreach(var rec in GetRecords()) { i++; System.Console.WriteLine(rec.GetString(1)); if …
15 c#  database  .net  resources 

2
** kwargsはアンチパターンですか?
ライブラリを内部的に呼び出す内部コードベースには多くのコードがあります-これらのライブラリには多くの引数があり(matplotlibを考えてください)、コードは特定のタスクのみを実行し、**kwargs呼び出された次の関数に単純に渡します。 例えば: def our_method(dataframe, **kwargs): result = do_something_with_data(dataframe) external_module.draw(result, **kwargs) 一方で**kwargs私たちのメソッド宣言のすべてのパラメータを繰り返すことから防止たちを、それはまた、呼び出し時に引数が有効であることが非常に不透明になりour_method、私はと呼ばれる方法を知っている必要があり、私は頻繁に知られたくないています- 。 これについてどう思いますか?
15 python 

1
Collection.stream()。filter()。forEach()は、各ループの標準と比較して非効率ですか?
IntelliJ IDEAは、次のfor-eachループをJava 8の "forEach"呼び出しに置き換えるために、今私に勧めました: for (Object o : objects) { if (o instanceof SomeObject) { doSomething(); } } 推奨される呼び出しは次のようになります。 objects.stream().filter(o -> o instanceof SomeObject).forEach(o -> doSomething()); Streamの基本的な機能がどのように機能するかを誤解していない限り、streamの使用は標準のfor-eachループのO(n)操作ではなくO(2n)操作であるように思われます。

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