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

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

5
関数ベースのRESTful APIの設計
私と友達の間で議論を解決してください。 現在、製品APIを設計しています。製品エンティティは次のようになります { "Id": "", "ProductName": "", "StockQuantity": 0 } 製品の販売はサードパーティが処理し、StockQuantityフィールドを減らすことができるように購入数量を通知する義務があります。 私のアプローチ: PUT /api/Product/{Id}/ --data { "StockQuantity": "{NewStockQuantity}" } サードパーティは、製品のクエリ、現在のStockQuantity購入数量に基づく計算、およびPUT新しい値でのリクエストの送信を担当します。 私の友人はサードパーティに計算を望まない。彼のアプローチ PUT /api/Product/{Id}/DecreaseStock --data { "PurchasedQuantity": "{PurchasedQuantity}" } したがって、計算を行って、 StockQuantity 私は関数ベースのエンドポイントを作成したくありません、そして彼は計算を行うためにサードパーティを信頼したくありません。 この問題に取り組むための正しい方法は何でしょうか?

4
あなた自身のクラスのための拡張メソッドをいつ書くべきですか?
私は最近、Addressどこかに、次に別の場所で定義されたデータクラスを持つコードベースを見ました。 fun Address.toAnschrift() = let { address -> Anschrift().apply { // mapping code here... } } このメソッドをアドレスに直接指定しないと混乱を招きました。拡張メソッドを使用するときに確立されたパターンまたはベストプラクティスはありますか?それとも、その本はまだ書かれている必要がありますか? この例のKotlin構文にも関わらず、C#またはそれらの機能を備えた他の言語にも適用されるので、一般的なベストプラクティスに興味があることに注意してください。
8 c#  design 

2
「進化的ソフトウェアアーキテクチャ」は矛盾ですか?
私の理解では、進化的アーキテクチャは、アーキテクチャを簡単に変更できるようにすることです。現在、アーキテクチャーは多くの場合、後で変更するのが難しいため、早期に正しく取得する必要があるものとして定義されています。 これはどのように組み合わされますか?進化的アーキテクチャとアーキテクチャの量を最小限に抑えることの間に違いはありますか?

4
イベントを使用した分離コンポーネント間の通信
相互に作用する小さな(> 50)小さなWebComponentsがたくさんあるWebアプリがあります。 すべてを切り離しておくために、原則として、どのコンポーネントも別のコンポーネントを直接参照できないようにしています。代わりに、コンポーネントはイベントを発生させ、(「メイン」アプリ内で)配線されて、別のコンポーネントのメソッドを呼び出します。 時間が経つにつれ、追加されるコンポーネントが増え、「メイン」のアプリファイルには次のようなコードチャンクが散らばっています。 buttonsToolbar.addEventListener('request-toggle-contact-form-modal', () => { contactForm.toggle() }) buttonsToolbar.addEventListener('request-toggle-bug-reporter-modal', () => { bugReporter.toggle() }) // ... etc これを改善するために、同様の機能をグループ化し、にClass関連性のある名前を付け、インスタンス化するときに参加要素を渡し、内の「配線」を次のClassように処理します。 class Contact { constructor(contactForm, bugReporter, buttonsToolbar) { this.contactForm = contactForm this.bugReporterForm = bugReporterForm this.buttonsToolbar = buttonsToolbar this.buttonsToolbar .addEventListener('request-toggle-contact-form-modal', () => { this.toggleContactForm() }) this.buttonsToolbar .addEventListener('request-toggle-bug-reporter-modal', () => { this.toggleBugReporterForm() }) …

1
アクセストークンと更新トークンを使用したトークンベースの認証
存続期間の短いアクセストークンと存続期間の長いリフレッシュトークンを使用して、REST APIのトークンベースの認証システムを実装しています。これは、関連するAPIエンドポイントの抽象的な概要です(HTTPSはすべてのエンドポイントに適用されます)。 エンドポイント: POST /register/ POST /login/ POST /logout/ POST /password/change/ 実装: POST /register/: リクエスト:クライアントがユーザー名、メール、パスワードをJSONで送信します。 サーバーアクション: 入力を検証し、データベースにユーザーを作成します(ユーザーID、ユーザー名、電子メール、パスワードハッシュを格納します)。 JWT形式で短期間有効なアクセストークンを作成します(ユーザーID、発行日、有効期限が含まれます)。 長期間有効な更新トークンをUUID文字列として作成し、データベースに保存します(ユーザーIDと更新トークンを保存します)。 応答:サーバーはJSONでアクセストークンと更新トークンを返します。 POST /login/: リクエスト:クライアントはJSONでユーザー名とパスワードを送信します。 サーバーアクション: 入力を検証し、データベースをチェックして資格情報が有効かどうかをチェックします。 資格情報が有効な場合、前述のように、有効期間が短いアクセストークンと有効期間が長いリフレッシュトークンを作成します。 レスポンス:と同じで/register/、アクセストークンと更新トークンをJSONで返します。 POST /logout/: 要求:クライアントはヘッダー内の更新トークンをトークンAuthorizationとして送信しBearerます。 サーバーアクション: 更新トークンデータベースをチェックして、更新トークンを検証します。 データベースから更新トークンを削除します。 注:これにより、アクセストークンは有効なままになりますが、有効期間は短いため(1時間程度なので、問題ないはずです)。 応答:ログアウト要求がJSONで正常に処理されたかどうかを返します。 POST /password/change/: リクエスト:クライアントはアクセストークンをAuthorizationヘッダーとしてBearerトークンとして送信し、古いパスワードと新しいパスワードをHTTPS経由でJSONで送信します。 サーバーアクション: アクセストークンをデコードしてユーザーを取得し、ユーザーの古いパスワードをデータベースで確認します。 データベース内のユーザーのパスワードハッシュを新しいパスワードのハッシュに設定します。 リフレッシュトークンデータベース内のユーザーに関連付けられたすべてのリフレッシュトークンを削除して、基本的に既存のセッションをログアウトします(有効期間の短いアクセストークンを残します)。 応答:パスワード変更リクエストがJSONで正常に処理されたかどうかを返します。 質問: このアプローチは安全ですか?具体的には: HTTPSを介して行われる場合、JSONを介したユーザー名とパスワードの送信は安全ですか?無許可のドメインがこのエンドポイントに電話をかけることをどのように防ぐことができますか?さらに、プログラムによるログインを防ぐにはどうすればよいですか? 更新トークンをデータベースに保存する前にハッシュ化する必要がありますか、それとも単なる偏執狂ですか? クライアントがWebブラウザーの場合、更新トークンをクライアントに安全に保存するにはどうすればよいですか? リフレッシュトークンを保存するための1つのアイデアは、ユーザーがログインすると、リフレッシュトークンをクライアントに送信するだけでなく、サーバーがトークンをフラグHttpOnly付きのCookieに保存することsecureです。承認は引き続きAuthorizationヘッダーを介して行われますが、クライアントが最初に読み込まれるときにGET、Cookieに有効な更新トークンが含まれているかどうかを確認するリクエストをエンドポイントに送信でき、有効な更新トークンが含まれている場合はJSONでユーザーに返します。つまり、Cookieが実際に使用されるのは、Cookie内の更新トークンをクライアントに返すときだけです。このアプローチは安全ですか?Cookieからリフレッシュトークンを要求するときに副作用がないため、CSRFを防ぐことができると思いますが、攻撃者がリフレッシュトークンを傍受する別の方法があります(HTTPSを想定)?

1
実行時間の長いスレッドにExecutorServiceを使用する理由
プロセスの存続期間中実行し続けるデーモンスレッドを生成するオブジェクトが必要です。議論のために、それは組み込みシステムのスレッドであり、いくつかの診断ポートでコマンドを受信して​​処理するのを待機しているとしましょう。しかし、それは本当に何でもあり得ます。主なアイデアは、長期間にわたって何かを見ているということです。一連のタスクを実行していません。 一般的なJavaの知恵によると、「インスタンス化しないThreadでくださいExecutorService。代わりに使用してください」です。(例えば、この答えを見てください)しかし、利点は何ですか?単一の長期実行スレッドを作成する手段としてスレッドプールを使用しても、意味がないようです。私がこれを書いた場合よりどのように良いでしょうか? class Foobar { public Foobar() { this.threadFactory = Executors.defaultThreadFactory(); ... } public Foobar(ThreadFactory threadFactory) { this.threadFactory = threadFactory; ... } public void start() { fooThread = threadFactory.newThread(new Runnable() { ... }); fooThread.setDaemon(true); fooThread.start(); } ... } 注:この質問は私の質問に似ていますが、答えはスレッドプールの使用方法のみを示し、理由は述べていません。

8
単一の責任の原則違反ですか?
私は最近、以下のクラスに関して別の開発者との議論に入りました: public class GroupBillingPayment { public void Save(IGroupBillingPayment model) { if (model == null || UserInfo.UserID == 0) { throw new Exception("GroupBillingPayment object or Current User Id is NULL , Please Contact Administrator."); } Data.GroupBillingPayment groupBillingPayment = RepositoryManager.GroupBillingPaymentRepository.GetById(model.GroupBillingPaymentID); Mapper.Map(model, groupBillingPayment); ServiceManager.GroupBilling.IsBillAlreadyCancelled(groupBillingPayment.GroupBillingID, THROW_ERROR); groupBillingPayment.UpdatedBy = UserInfo.UserID; groupBillingPayment.UpdatedOn = DateTime.Now; RepositoryManager.GroupBillingPaymentRepository.Update(groupBillingPayment, false); …

6
戦闘(認識)オーバーエンジニアリングvs流れに乗る[終了]
休業。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善してみませんか?この投稿を編集して、事実と引用で回答できるように質問を更新してください。 3年前休業。 私のデザインとは異なるアプローチを持つチームに参加しました。私はYAGNIのデザインへのアプローチを信じています。たとえば、メソッド(インターフェース、クラス)が使用されていない場合は、削除する必要があります。それでおしまい。 私のチームの人々はモジュール式のアプリを構築しており、モジュールの1つは「フレームワーク」として認識されています。アプリはこのフレームワークの唯一のユーザーであり、現時点でクライアントを増やす計画はありません。ただし、このフレームワークのコードの一部は、あたかも後で使用されるかのように作成および保守され、一貫性と完全性はYAGNIよりも優れています。抽象化が必要になることのない場所に抽象化があるなど。 私はいくつかのことを議論しようとしましたが、仮に仮に説得するにしても、それぞれのポイントにはかなりの時間がかかります。 「フローに沿って」、個人的な問題なしに追加のコードを書くことができます。それは、後に維持するために、最も可能性の高いより多くの時間をコードに今私に多くの時間がかかる、となりますが、余分にも時間がかかり、圧力を加える何かをしないように、それぞれの議論を。 問題は、異なる意見の場合、より大きな不利益、不要であるが「適切な」コード、または定数の引数と壊れたチームのダイナミクスは何をするのでしょうか?

1
組み込みシステムの構成メニューの設計上の考慮事項
私は、いくつかのボタンと小さなグラフィックディスプレイでユーザーとインターフェイスする組み込みシステムに取り組んでいます。 余談ですが、私は組み込みシステムを使用しているので、動的なメモリ割り当てをできるだけ回避したいと思います。std :: vectorのようなものは利用できません。 次のように、クラシックなネストされたメニュー構造を使用して構成メニューを実装する必要があります。 Level A Node 1 -> Level B Node 1 -> Level C Node 1 -> Level B Node 2 -> Level B Node 3 Level A Node 2 Level A Node 3 ここでの最善のアプローチについてはよくわかりません。複合パターンを使用するなど、このようなものにアプローチするいくつかの方法について読みました。しかし、私はいつも「紙の上」では良さそうに見えても、実装するのは面倒そうなものにぶつかります。 私の一般的な考えはMenuNode、初期化時にそのサブノードと親ノードについて知っているクラスを持つことです。Menuクラスは、ノードナビゲーションおよび処理を扱うことができます。明らかに、すべてMenuNodeが次のような特定の動作を実行/実装する必要があります。 Menu何を表示したいかを報告します(実際のレイアウト/配置はの問題ではありませんMenuNode)。 ユーザー入力に反応する(値を増減する/ボタンを押すなど) 関心のある実際の値にアクセスする(ApplicationSettingsクラスに属している) これを実装する最良の方法は何でしょうか? (抽象的な)MenuNode基本クラスを使用して、すべてのメニューノード項目のサブクラスを作成します。初期化中に、ApplicationSettings必要になる可能性のある他の依存関係へのポインタを提供できます。どういうわけか、それぞれが一度だけインスタンス化される10個の派生クラスを作成するのは間違っていると感じています。 MenuNodeすべてのノードに同じクラスを使用し、関数を解放するコールバックを通じて機能を実装します。私が読んだことから、そのかなり一般的なものは、自由な関数をオブジェクトと「結合」することです。しかし、それは物事を複雑にしてしまうような気がします。ReportButtonPress()などのメンバーごとに、初期化中に実際の実装のコールバックを提供する必要があります。 ここで見落としているものがあると思います。

4
一般的なエラーを無視して、プログラムが[クローズ]から回復する場合
休業。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善してみませんか?この投稿を編集して、事実と引用で回答できるように質問を更新してください。 3年前休業。 毎日何百ものCURL要求、SMTP要求、およびその他の要求を行うプログラムがあります。1%未満の時間で、CURLまたはSMTP要求は失敗します。問題の原因は外部にあり、100%信頼できるように修正することはできません。私のプログラムはいつでもそれから回復することができ、そこから人間の相互作用は必要ありません。何かが失敗したときに電子メールアラートを送信するシステムを導入しています。私が受け取るものの大部分は、これらの無害なCURLおよびSMTPの失敗です。 プログラムが回復する一般的な障害について、電子メールアラートを送信しないでください。

4
メンバー関数がクラスプロパティ/メンバー変数を使用しない場合、OOP原則に違反しますか?
私は、ファイルを開いたり、読んだり、書き込んだりできる相互作用する既存のクラスを持っています。そのためにファイルの変更を取得する必要があります新しいメソッドを追加する必要があります これが私のクラス定義で、新しいメソッドを追加したいとします。 class IO_file { std::string m_file_name; public: IO(); IO(std::string file_name); + time_t get_mtime(file_name); + OR + time_t get_mtime(); }; 2つのオプションがあります- 空のオブジェクトを作成してから、ファイルの変更時刻を取得するメソッドの引数にfile_nameを渡します。 オブジェクト構築時にファイル名を渡し、単純にメンバー変数を操作するメンバー関数を呼び出します。 どちらのオプションも目的を果たします。また、2番目のアプローチは最初のアプローチよりも優れていると思います。しかし、私が理解していないのはどのようにですか?メンバー変数を利用しないので、最初のアプローチは悪いデザインですか?オブジェクト指向設計のどの原則に違反しますか?メンバー関数がメンバー変数を使用しない場合、そのメンバー関数は常に静的にする必要がありますか?

2
ここでクラスを分離しすぎていませんか?
私はリアルタイムの地形レンダリングエンジンに取り組んでいます。QuadTreeクラスとNodeクラスがあります。QuadTreeクラスは、カメラの場所に応じてツリーを展開または折りたたみます。したがって、QuadTreeがNodeオブジェクトの存続期間を担当することは理にかなっています。問題は、その存続期間に関連付ける必要があり、QuadTreeとは何の関係もない多くのデータがあることです。これらのデータは相互に関連していなくてもかまいません。私は成功せずにクラスを正しく分離するクリーンな方法を探していました。すべての変更(場合によってはマイナーな変更も)には、いくつかのファイルを介した変更が必要で、ほとんどの場合、それに関連しないファイルが必要です。ようやく機能するように見えるものがありますが、それをあまりにも切り離そうとしているので、あまりメリットがないために複雑さが増しています。これは私がそれをした方法です: 私のQuadTreeクラスは、ツリー以外のものを処理するべきではありません。しかし、ノードを作成するたびに、これらのノードにデータを関連付ける必要があります。これはQuadTreeクラスで行うためにクラスを汚染するため、QuadTreeとこれらのデータを作成することを仕事とするクラスの間で通信するためのインターフェースを追加しました。この時点で、私はそれを正しい方法で行っていると思います。疑似コード: class QTInterface { virtual void nodeCreated( Node& node ) = 0; virtual void nodeDestroyed( Node& node ) = 0; }; class QuadTree { public: QuadTree( ...., QTInterface& i ) : i( i ) {} void update( Camera camera ) { // .... i.nodeCreated( node ); // .... i.nodeDestroyed( …

1
SQLiteデータベースファイルはどこに保存しますか?
現在は効果のないデザインの、1つの言語(現時点では英語)の外国語を学習するためのアプリケーションを作成しています。 単語の保存にはJavaとSQLite-jdbcを使用しています。起動後、アプリケーションはコンマ区切りのワードリストをダウンロードし、各値のペアをデータベースに挿入します。余分なgithubリポジトリでワードリストをホストしました。これは、データベースファイルを開発gitリポジトリ内に保存するべきではないと考えていたためです。そのバイナリなので、データベースでsthを実行するたびに、データベースファイルのハッシュが変化します。読みにくいコミットメッセージを作成する必要があり、データベースに対する実際の変更を理解するのが難しいため、私はそれが好きではありません。 したがって、私の実際の質問: gitリポジトリ内に保存するよりもDBファイルを保存するよりエレガントなソリューションはありますか?現在のデータベースファイルを別のファイルホストに保存するだけですか?そのような状況のベストプラクティスは何ですか?
8 design  sqlite 

2
すべてのメソッドが仮想ではないのか、各クラスに少なくとも1つのインターフェイスがないのはなぜですか?
これは.NETプラットフォームに関するより哲学的な質問ですが、他の言語でも役立つかもしれません。私は多くの単体テストを行っていますが、特に私がしばしば苦労しているサードパーティのコンポーネントを使用している場合はそうです。.NETでは、コンポーネントの設計者に、どのメソッドを仮想化するかどうかを選択するという大きな主張があります。1つはコンポーネントの使用方法(仮想化する意味がある)、もう1つはコンポーネントのモック機能です。Shimsを使用してサードパーティのコンポーネントをモックアップできますが、これは多くの場合、設計や複雑さを悪化させます。.NETでのすべてのメソッドの仮想化(JAVAには最初からあります)についての議論は、パフォーマンスに関するものでした。しかし、それはまだ問題ですか?なぜすべてのメソッドが.NET virtualではないのか、または各クラスに少なくとも1つのインターフェイスがないのはなぜですか?

2
ログを国際化することは意味がありますか?
ログを国際化するための有効なユースケースは何ですか?特に、Webアプリケーションにとって意味のある用途はありますか。 私はからWebアプリケーションが使用するロギングAPIの変換に取り組んでいるlog4jのをslf4j、インターフェイスが上抽象的に使用されていることに気づいたlog4jの実装をサポートする国際化。また、との両方が国際化log4jをslf4jサポートしていることにも気付きました。 現在、国際化は、エンドユーザーがログを表示できるデスクトップアプリケーションをプログラミングするときに役立ちますが、このロギングファサードは、一般的に英語を使用する必要がある開発者が、いくつかのWebアプリケーションのサーバー側でのみ使用します。 。

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