ソフトウェア工学

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

3
ソフトウェアアーキテクチャvsシステムアーキテクチャvsクラス図?
私は次の用語についてかなり混乱しています。 ソフトウェアアーキテクチャ ソフトウェアアプリケーションアーキテクチャは、パフォーマンス、セキュリティ、管理性などの一般的な品質属性を最適化しながら、すべての技術的および運用上の要件を満たす構造化ソリューションを定義するプロセスです。さまざまな要因に基づいた一連の決定が含まれ、これらの決定はそれぞれ、アプリケーションの品質、パフォーマンス、保守性、および全体的な成功に大きな影響を与える可能性があります。(マイクロソフト) システムアーキテクチャー システムアーキテクチャは、システムの構造、動作、およびその他のビューを定義する概念モデルです。1アーキテクチャ記述は、システムの構造と動作に関する推論をサポートする方法で編成された、システムの正式な記述と表現です(wiki) クラス図 ソフトウェアエンジニアリングでは、Unified Modeling Language(UML)のクラス図は、システムのクラス、その属性、操作(またはメソッド)、およびオブジェクト間の関係を示すことにより、システムの構造を記述する静的構造図の一種です。(wiki) これらの説明を読んだ場合、これらはすべてアプリケーションの異なるモジュール間の相互作用を説明しています。しかし、これらの違いは何ですか? これらの用語を比較するために私が考え/試みたもの: クラス図はシステムアーキテクチャの形式ではありません。上記の説明(structure, behavior, and more views of a system)は、アーキテクチャに実装の詳細が存在しないことを意味するのに対し、クラス図は実装を記述し、おそらくアーキテクチャではなく設計の方向にありますか? ソフトウェアアーキテクチャはアプリケーション自体に焦点を合わせているのに対して、システムアーキテクチャは外部対話(データベースなど)も含むアーキテクチャだと思いますか?

1
2000以上のクライアントマシンのアプリケーションサーバーとしてのRESTサービス。それは良い考えですか?
2000以上のマシンにデプロイされるjavaFxのUIを使用してシステムを構築します(最小は2000ですが、さらに多くなります-5000台のマシンに到達できます)。 他の理由/制限のため、マシンにインストールする必要があるため、Webブラウザーインターフェイスでは実行できません。 2000台以上のマシンは、異なる地理的ロケーショングループに属します。一般に接続は良好ですが、より多くの遠隔地ではそれほど良好ではない場合があります。 データベースに直接アクセスする代わりに、Spring + Spring Boot + Spring Data(java)を使用してRESTサービスクラスターを構築することを考えています。 RESTサービスはJsonを受け入れて返します。 私はそれが良い考えだと思う: サービスはデータベース接続プールとして機能します(データベースで2000以上の接続を行うと問題が発生すると思います)。 一部のクエリを処理するために、他の読み取り専用データベースへのログ配布を備えたデータベースを使用することができます。 より多くのマシンを追加してRESTサービスを実行できるため、スケーラビリティが向上します。 セキュリティおよび帯域幅節約の理由で、圧縮されたHTTPSを使用することができます。 2000以上のマシンを再デプロイせずに、ビジネスエンティティに集中的な変更を加えることができます。 他のシステムとの統合性が向上します(RESTサービスをポイントするだけです)。 それは本当に良いアイデアですか? 肯定的または否定的な経験を共有できますか? ありがとうございました。
11 java  design  rest  spring 

4
完全な機能を備えたアプリケーションを構築するか、必要最低限​​のアプリケーションを構築してから、徐々に機能を追加する必要がありますか?
私は、製造現場のスケジューリングプログラムの作成をITに任せている製造工場で働いています(これは非常に必要です)。他の経験に基づいて、より少ない時間で利用可能な基本的なフレームワークを構築し、機能を追加することでその上に構築するか、完全に実装されたソリューションをすぐに作成して開始する方が良いでしょうか?私は約1年しかデベロッパーではなく、このサイズのアプリの初期作成の経験はあまりありません。私は、ある種のデジタルスケジュールが非常に必要なため、ベアボーンアプリが最初に行く方法であるという考えに傾いてきましたが、事実の後にランダムな機能を追加すると少し厄介になる可能性があります。あなたが同じ状況にあった場合、あなたはどの道に向かって傾くでしょうか?

1
論理および物理アーキテクチャ図を最新の状態に保つ
複数の開発者がいる分散システムを含むソフトウェア開発プロジェクトでは、論理および物理アーキテクチャの図を作成することがベストプラクティスですが、私の経験では、これらの図は常にプロジェクトの開始時に適切に管理されていますが、プロジェクトのリリース時に更新されませんメンテナンスフェーズが開始されます。 多くの分散プロセスを持つ複雑なプロジェクトの場合、最初のリリースの前であっても、誰も知識を持っていないため、ダイアグラムはすぐに古くなったり不正確になったりする傾向があります。 このような背景から、コミュニティに次の質問をしたいと思います。 正確で最新の論理および物理アーキテクチャ図を作成することはどれほど重要ですか? それらを最新の状態に保つのに役立つツールやプロセスはありますか? それらを最新の状態に保つ責任は誰にありますか?システム管理者、開発者、QAチームはどのように貢献できますか?

4
C#のインターフェイスで前提条件(LSP)を指定する方法は?
次のインターフェースがあるとしましょう- interface IDatabase { string ConnectionString{get;set;} void ExecuteNoQuery(string sql); void ExecuteNoQuery(string[] sql); //Various other methods all requiring ConnectionString to be set } 前提条件は、いずれかのメソッドを実行する前にConnectionStringを設定/初期化する必要があることです。 IDatabaseが抽象クラスまたは具象クラスである場合、コンストラクターを介してconnectionStringを渡すことにより、この前提条件をある程度達成できます。 abstract class Database { public string ConnectionString{get;set;} public Database(string connectionString){ ConnectionString = connectionString;} public void ExecuteNoQuery(string sql); public void ExecuteNoQuery(string[] sql); //Various other methods all requiring …

3
例外や冗長性なしに入力検証を実行する方法
特定のプログラム用のインターフェイスを作成しようとすると、通常、検証されていない入力に依存する例外をスローしないようにします。 よくあることは、次のようなコードを考えたことです(これは単なる例であり、実行する機能は気にしないでください(Javaの例))。 public static String padToEvenOriginal(int evenSize, String string) { if (evenSize % 2 == 1) { throw new IllegalArgumentException("evenSize argument is not even"); } if (string.length() >= evenSize) { return string; } StringBuilder sb = new StringBuilder(evenSize); sb.append(string); for (int i = string.length(); i < evenSize; i++) { sb.append(' …

6
スクラム-スプリント外で作業する開発者
スクラムチーム 3 x開発者 2 xテスター 1 x自動化テストアナリスト 開発者がテストせず、テスターが開発しないという点で、私たちは多機能チームではありません。これが問題の根本原因だと思います。 現在、2週間のスプリントを行っています。 スプリントの開始時には誰もが忙しく、開発者は開発作業を開始し、テスターはテストの準備(テストケースの作成など)を行っています。 テスターが準備を完了すると、開発作業が完了するのを待っているか、開発作業が完了して開発者がフィードバック/バグを待っています。 開発者はここでitい足を踏み入れ、現在のスプリントの範囲外にあるバックログのアイテムの作業を開始します。これにより、現在のスプリントで常に次のスプリントを開発するという奇妙な影響が生まれています。私にはこれは正しくないと思う。 経営者の観点からは、彼らは開発者が机に座って何もしないよりはむしろ仕事をすることを望んでいますが、同時に、スクラムチームの目標と焦点は現在のスプリントのみにあるべきだと感じています。私たちのチームが多機能であることを願っていますが、残念ながらそれは達成できません。テスターに​​は開発作業を行うのに必要なスキルがなく、開発者の大多数はテストが彼らの下にあるという意見を持っています。 これはスクラムの問題と見なされますか?これに対する解決策はありますか?スクラムは多機能チームでのみ機能しますか? 可能であれば、これに関する他の人々の経験を知りたいです:)
11 agile  scrum 

2
DDDを使用せず、ESを使用しない(または使用する)CQRS-書き込みモデルとは何か、読み取りモデルとは何ですか?
私の知る限り、CQRSの背後にある大きなアイデアは、コマンドとクエリを処理するための2つの異なるデータモデルを持つことです。これらは「書き込みモデル」および「読み取りモデル」と呼ばれます。 Twitterアプリケーションのクローンの例を考えてみましょう。コマンドは次のとおりです。 ユーザーは自分で登録できます。CreateUserCommand(string username)放出するUserCreatedEvent ユーザーは他のユーザーをフォローできます。FollowUserCommand(int userAId, int userBId)放出するUserFollowedEvent ユーザーは投稿を作成できます。CreatePostCommand(int userId, string text)放出するPostCreatedEvent 上記では「イベント」という用語を使用していますが、「イベントソース」イベントを意味するものではありません。読み取りモデルの更新をトリガーする信号を意味します。イベントストアはありませんが、これまではCQRS自体に集中したいと考えています。 クエリは次のとおりです。 ユーザーは投稿のリストを見る必要があります。 GetPostsQuery(int userId) ユーザーは、フォロワーのリストを見る必要があります。 GetFollowersQuery(int userId) ユーザーは、フォローしているユーザーのリストを見る必要があります。 GetFollowedUsersQuery(int userId) ユーザーは、「フレンドフィード」-すべての友達のアクティビティのログ(「友達のジョンが新しい投稿を作成しました」)を表示する必要があります。 GetFriedFeedRecordsQuery(int userId) 処理CreateUserCommandするには、そのようなユーザーが既に存在するかどうかを知る必要があります。したがって、この時点で、自分の書き込みモデルにはすべてのユーザーのリストが必要であることを知っています。 処理FollowUserCommandするには、userAがすでにuserBをフォローしているかどうかを知る必要があります。この時点で、書き込みモデルにすべてのユーザーフォローユーザー接続のリストが必要です。 そして最後に、処理するCreatePostCommandために他に何も必要ないと思います。なぜなら、私にはのようなコマンドがないからUpdatePostCommandです。それらがある場合、投稿が存在することを確認する必要があるため、すべての投稿のリストが必要になります。しかし、この要件がないため、すべての投稿を追跡する必要はありません。 質問#1:実際に使用する「モデルの書き込み」という用語を使用するのは実際に正しいですか?または、ESの場合、「書き込みモデル」は常に「イベントストア」を表しますか?もしそうなら、コマンドを処理する必要があるデータとクエリを処理する必要があるデータの間に何らかの分離がありますか? を処理GetPostsQueryするには、すべての投稿のリストが必要です。つまり、読み取りモデルにはすべての投稿のリストが必要です。私はを聞いてこのモデルを維持しPostCreatedEventます。 GetFollowersQueryとの両方を処理するには、GetFollowedUsersQueryユーザー間のすべての接続のリストが必要です。このモデルを維持するために耳を傾けるつもりですUserFollowedEvent。ここに質問#2があります:書き込みモデルの接続リストをここで使用しても実質上問題ありませんか?または、将来、書き込みモデルよりも詳細な情報が必要になる可能性があるため、個別の読み取りモデルを作成する必要がありますか? 最後に、処理するGetFriendFeedRecordsQueryには次のことが必要です。 聞く UserFollowedEvent 聞く PostCreatedEvent どのユーザーがどの他のユーザーをフォローしているかを知る ユーザーAがユーザーBをフォローし、ユーザーBがユーザーCをフォローし始めると、次のレコードが表示されます。 ユーザーAの場合:「友達ユーザーBはユーザーCのフォローを開始しました」 ユーザーBの場合:「ユーザーCのフォローを開始しました」 ユーザーCの場合:「ユーザーBがあなたをフォローしています」 ここだ質問#3:私は接続のリストを取得するために使用すべきかのモデル?書き込みモデルを使用する必要がありますか?読み取りモデルを使用する必要があります- GetFollowersQuery/ GetFollowedUsersQuery?または、GetFriendFeedRecordsQueryモデル自体UserFollowedEventにすべての接続の独自のリストを処理させ、維持させる必要がありますか?
11 cqrs  read-model 

6
命名:明快さのために簡潔さを犠牲にするべきですか?
たとえば、次の関数は、入力フィールドの名前とエラーを含む配列をループします。これは、検証フィールドの名前を確認し、エラー情報を無効なフィールド配列にプッシュすることにより行います。 簡潔にこれを書く方が良いですか? addInvalidField (field, message) { const foundField = this.invalidFields.find(value => { return value.name === field.name }) const errors = foundField.errors if (!errors.some(error => error.name === message)) { errors.push({ name: message, message }) } }, または、このように具体的にしますか? addInvalidField (validatingField, message) { const foundField = this.invalidFields.find(invalidField => { return validatingField.name === invalidField.name …

5
サブクラス型を要求しないようにするための優れた設計方法は何ですか?
プログラムがオブジェクトのクラスを知る必要がある場合、通常は設計上の欠陥を示しているので、これを処理するための適切なプラクティスを知りたいと読みました。Circle、Polygon、Rectangleなど、さまざまなサブクラスを継承するShapeクラスを実装しています。また、CircleがPolygonまたはRectangleと衝突するかどうかを知るためのさまざまなアルゴリズムがあります。次に、Shapeの2つのインスタンスを取得し、一方が他方と衝突するかどうかを知りたいと仮定します。そのメソッドでは、どのアルゴリズムを呼び出すべきかを知るために衝突しているオブジェクトがどのサブクラスタイプであるかを推測しますが、これは悪いデザインや練習?これが私が解決した方法です。 abstract class Shape { ShapeType getType(); bool collide(Shape other); } class Circle : Shape { getType() { return Type.Circle; } bool collide(Shape other) { if(other.getType() == Type.Rect) { collideCircleRect(this, (Rect) other); } else if(other.getType() == Type.Polygon) { collideCirclePolygon(this, (Polygon) other); } } } これは悪いデザインパターンですか?サブクラス型を推測せずにこれをどのように解決できますか?

2
トランザクションを使用したビジネスロジックとDBロジックの分離
アプリケーションには3つのレイヤーがあります。外部APIを提供するサービスレイヤー。ビジネスロジック用のBOレイヤー、およびデータベース接続用のDAOレイヤー。 ファイルを更新するたびに、フォルダ内の何か、たとえば「最終変更日」も変更したいとします。これは、トランザクションで実行する必要があります。成功し、ファイルとフォルダーの両方が編集されます。または、障害が発生し、トランザクションがロールバックされるため、両方のオブジェクトが以前の状態になります。 「ファイルが編集されたときにフォルダーを編集する」アクションは、純粋にビジネスロジックです。したがって、これはBOレイヤーに属していることを意味します。ただし、データベースにはObjectifyを使用しているため、トランザクションを開始するにはofy()。transact(...)を呼び出す必要があります。BOレイヤーでこの関数を呼び出すと、ビジネスレイヤーでデータベース固有の呼び出し(Objectify)が発生するため、デザインが破損します。 この問題のクリーンなソリューションは何でしょうか?

5
単一の障害が一括操作に失敗する必要がありますか?
私が取り組んでいるAPIには、IDの配列を受け入れる一括削除操作があります: ["1000", ..., "2000"] 削除操作は自由に実装できたので、すべてをトランザクション対応にすることにしました。つまり、1つのIDが無効な場合、リクエスト全体が失敗します。これを厳密モードと呼びます。 try{ savepoint = conn.setSavepoint(); for(id : IDs) if( !deleteItem(id) ){ conn.rollback(savepoint); sendHttp400AndBeDoneWithIt(); return; } conn.commit(); } 別の方法(ソフトウェアスイートの別の場所で実装)は、バックエンドでできることを実行し、アレイでエラーを報告することです。ソフトウェアのその部分はより少ないリクエストを扱うので、理論的にはレスポンスが巨大な配列になることはありません。 リソース不足のサーバーで発生した最近のバグにより、コードを再度確認し、今は元の決定に疑問を抱いていますが、今回はベストプラクティスではなくビジネスニーズによって動機付けられています。たとえば、リクエスト全体が失敗した場合、ユーザーは再試行する必要がありますが、いくつかのアイテムが削除された場合、ユーザーはアクションを終了し、管理者に残りの作業を依頼できます(バグの修正に取り組んでいる間) !)。これが許容モードになります。 私はこの問題に関するガイダンスをオンラインで探してみましたが、手ぶらで出てきました。だから私はあなたに来ます:この種のバルク操作で最も期待されることは何ですか?もっと厳しくするべきですか、それとももっと寛容にすべきですか?

3
Entity FrameworkとAnemic Domain Modelの回避
ビジネスロジックでは、次のようなメソッドが定義されている場合があります。 User.ResetCourse(Course courseToReset) 問題は、ユーザーとコースの両方がEntity Frameworkプロキシオブジェクトであるということです。つまり、ユーザーまたはコースのいずれかのナビゲーションプロパティにヒットすると、それらのオブジェクトはIQuery可能ではないため、通常どおりに繰り返されるため、データベースに大きなヒットを引き起こす可能性があります。 これを解決するために、署名を次のように変更しました。 User.ResetCourse(MyDBContext db, Course courseToReset) つまり、データベースに直接クエリを実行して必要な変更を効率的に行うことができますが、データベースコンテキストをビジネスオブジェクトに渡すことは非常に間違っているようです。 その後、ユーザーにサービスレイヤーを移行しました。つまり、次のようなものがあります。 CourseService.ResetForUser(Course courseToReset, User forUser) このサービスには、作成時に挿入されたDBContextへの参照がありますが、現在のビジネスオブジェクトは、動作のない単なるデータバッグです(つまり、Anemic Domain Model)。 どうすればこれを回避できますか?

9
スクラムチームのインプットは何ですか?
スクラムチームは、通常のスクラムの役割で構成されています。UI / UXデザイナーはおらず、開発者は製品所有者とUI / UXを操作します。ここに問題があります。バックログを作成しようとするたびに、スプリントの開始前に正確なUI / UXデザインを定義していないため、スプリント中にUI / UXデザインを完成させようとして時間がかかりすぎます。 これは、機能の分析とアーキテクチャにも当てはまります。機能に関するすべての可能な詳細は、スプリントの開始前に開発者に提供されるべきか、それとも機能内のタスクであると考えますか?私たちはこれを経験しており、基準を持たないいくつかの未定義の機能をもたらします。
11 agile  scrum 

2
C ++の線形代数パッケージを使用する場合、遅延と見なされますか?
最初に、質問を実際に述べる前に、背景を説明します。私は物理学を研究しており、私のプログラミングクラスはすべて、MATLABのような簡単なプログラミング言語で行われています。簡単に言うと、言語はあなたのために多くのことを考えているということです...次の数年間、私はコンピューターサイエンスのコースを受講し、プログラミングのキャリアを追求することを考えています。 多くの大学のコースがC ++であると考えると、MATLABと同様の構文を持つ線形代数パッケージ(Armadillo)を使用することは怠consideredと見なされますか? 現在、遺伝的アルゴリズムをコーディングしていますが、MATLABでは高速になりましたが、C ++ではこれらのパッケージを使用せずに多くの時間を費やしています。 実生活ではどのように機能しますか?どのパッケージを使用できますか? たとえば、armadilloでC ++の知識を構築したくないし、「vector.h」、「algorithm」、「list」など、他のより広く使用されているパッケージの深い知識も持ちたくない
11 c++  experience 

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