ソフトウェア工学

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

1
型パラメーターの型引数を推論する手法の名前は?
セットアップ:Iterator型パラメーターを持つと呼ばれる型があるとしましょうElement: interface Iterator<Element> {} 次に、をIterable返す1つのメソッドを持つインターフェースがありますIterator。 // T has an upper bound of Iterator interface Iterable<T: Iterator> { getIterator(): T } Iteratorジェネリックであることの問題は、型引数を指定する必要があることです。 これを解決する1つのアイデアは、イテレータのタイプを「推測」することです。次の疑似コードは、Elementへの型引数であると推定される型変数があるという考えを表していますIterator。 interface <Element> Iterable<T: Iterator<Element>> { getIterator(): T } そして、次のような場所で使用します。 class Vec<Element> implements Iterable<VecIterator<Element>> {/*...*/} このの定義は、その定義の他の場所ではIterable使用していませんElementが、実際の使用例では使用しています。を使用する特定の関数は、双方向のイテレータなど、特定の種類のイテレータのみを返すs Iterableを受け入れるようにパラメータを制約できる必要もあります。そのIterableため、返されるイテレータは要素タイプだけではなくパラメータ化されます。 質問: これらの推定された型変数の確立された名前はありますか?テクニック全体についてはどうですか?特定の命名法を知らないために、この例を実際に検索したり、言語固有の機能について学ぶことが困難になっています。 総称を持つすべての言語がこの手法を備えているわけではありません。これらの言語で同様の技術の名前はありますか?

2
例外の粒度
私は、次のような彼らは、一般的な例外を好む数人の友人とI.間の論争に実行したClientErrorExceptionとServerErrorException私は物事にもっと具体的に作ることを好むのに対し、例外のフィールドとして詳細に。たとえば、次のような例外がいくつかある場合があります。 BadRequestException AuthenticationFailureException ProductNotFoundException これらはそれぞれ、APIから返されたエラーコードに基づいて構築されています。 例外の利点に従うと、これはJavaにとって慣用的なようです。しかし、私の友人の意見は全く珍しいことではありません。 コードの読みやすさとAPIの使いやすさの点で好ましい方法はありますか、それとも本当に好みに帰着するだけですか?

6
大学生と開発プロセスを実装する方法
ソフトウェア開発者としての最初の仕事で、私のチームはアジャイル/スクラムを使用してプロジェクトのワークフローを管理しましたが、それはかなりうまくいきました。経験豊富なメンターが私を正しい方向に導いてくれました-私は彼らに大きな感謝の気持ちを抱いています。私はそこで数年間働いた後、数か月前に新しい機会に移りました。 現在の仕事に早送りします。私は大学の教授のもとで働いています。私は大学にいるので、ほとんどすべてのプログラマーは学生です(彼らは安価で豊富です!)私の上司には管理経験がありますが、ソフトウェア開発の経験はなく、ソフトウェアチームは常に上司の頭にいるわけではありません。 。これらの条件は、いくつかの非常に質の悪いソフトウェアを作成するための完璧な環境を作り出しました。ソフトウェアプロジェクトは少し悪党であるように見え、設計することを考えておらず、いくつかの本当に恐ろしい慣行を採用しています。物事が良くなることを知っています。 開発プロセスを実装して、全員を軌道に乗せ、コードの品質を向上させ、より安定したソフトウェアを展開したいと考えています。どこから始めればいいのかわからない。 私は、言うまでもなく、「スクラムを使用する」、「かんばんボードを設定する」、「アジャイルを見てください」などの回答を探していません。(アイデアは高く評価されますが)。具体的には、この作業環境の開発プロセスを実装する方法について洞察を得たいと思っています。従業員は通常、次に進む前の1〜2年の間に働き、一般的に経験が浅く、全員を含む毎日のスタンドアップミーティングをスケジュールすることはほとんど不可能です。 そのような職場では、品質、効率、コミュニケーションをどのようにして育てるのでしょうか。 更新:いくつかの回答とコメントを読んだ後、私はいくつかの追加の背景を提供すると思いました。 私は自分自身のソフトウェア開発の芸術のマスターを検討していないだろうが、私は思います、私はそれを見たときに悪いプログラミングを認識するのに十分な経験を積みました。開発者が1〜2分で作業した後、開発者が才能があるかどうかを判断できます。私は問題をスマートに解決する方法を見つける自分の能力に満足していますが、本当に経験が足りない領域は、他の開発者が関与するプロジェクト管理です(そのため、私はここですべての素晴らしい人々に助言)。 私は、このオフィスに来るすべての学生が完全な弱者であるように聞こえました。ここには悪い卵がいくつかありましたが、私が会った学生の大多数は知的で、学びたいと思っており、仕事に熱心です。一部はまだ始まったばかりで、何を知らないのか分からない。そして、それは大丈夫です。私がプログラミングを始めたとき、私は元気がありませんでした!

3
For-ifアンチパターン
for-ifアンチパターンについてこのブログ投稿を読んでいましたが、なぜそれがアンチパターンであるのか理解できません。 foreach (string filename in Directory.GetFiles(".")) { if (filename.Equals("desktop.ini", StringComparison.OrdinalIgnoreCase)) { return new StreamReader(filename); } } 質問1: それが理由であるreturn new StreamReader(filename);内部for loop?または、forこの場合ループが必要ないという事実ですか? ブログの作者が指摘したように、これのクレイジーでないバージョンは次のとおりです: if (File.Exists("desktop.ini")) { return new StreamReader("desktop.ini"); } の作成前にファイルが削除されるとStreamReader、を取得するため、どちらも競合状態になりますFile­Not­Found­Exception。 質問2: 2番目の例を修正するには、ifステートメントなしで書き直し、代わりにをStreamReadertry-catchブロックで囲み、それがスローされるFile­Not­Found­Exception場合は、それにcatch応じてブロックで処理しますか?

5
マイクロサービス:MonolithFirst?
私はすべての長所と短所、いつ、なぜなどの高レベルの概要を取得しようとするマイクロサービスアーキテクチャを研究してきました。私が読んで/見ている情報の多くは、ThoughtWorks(Martin Fowler、Neal Fordなどからのものです) al)。 この問題に関するMartin Fowlerの仕事の大部分は数年前のものであり、Microservices(プログラミングの一般的な名称ではないが)がまだ若かったため、私はその多くを少しずつ理解しました。 特に、これは次のとおりです。 マイクロサービスアーキテクチャを使用するチームの話を聞いていると、共通のパターンに気づきました。 成功したマイクロサービスストーリーのほとんどすべては、大きくなりすぎて分割されたモノリスから始まりました。 最初からマイクロサービスシステムとして構築されたシステムについて聞いたほとんどすべての場合、それは深刻な問題に終わっています。 このパターンにより、多くの同僚は、アプリケーションが価値があるほど十分に大きいアプリケーションであっても、マイクロサービスで新しいプロジェクトを開始すべきではないと主張しました。。 (参照:https : //martinfowler.com/bliki/MonolithFirst.html-彼らを強調) さて、3年後、マイクロサービスがよりユビキタスな言葉になりましたが、新しいシステムは通常、最初により大きい(-microservice-but-smaller-than-monolith)サービスチャンクを用意し、それらは進化的測定の一部としてより細かく? または、上記のステートメントとは対照的に、きめ細かなマイクロサービスアーキテクチャを使用してプロジェクトをゼロから開始する基準はありますか? 正気な一般的なアプローチのようですが、コミュニティの考えに興味があります。

3
値で渡されるパラメーターの値を変更しない理由はありますか?
関数の本体にある値渡しパラメーターの値を変更することに対する、またはそれに対する反対の客観的でサポート可能なソフトウェアエンジニアリングの引数はありますか? 私のチームで繰り返されるスパッツ(大部分はおもしろい)は、値によって渡されるパラメーターを変更する必要があるかどうかです。チームのいくつかのメンバーは、パラメーターを決して割り当ててはならないことに固執しているため、最初に関数に渡された値を常に問い合わせることができます。パラメータは、メソッドを呼び出す構文によって初期化されたローカル変数に過ぎないと私は同意しません。値渡しパラメーターの元の値が重要な場合は、ローカル変数を宣言してこの値を明示的に格納できます。私たちのどちらかが私たちの立場を非常によくサポートしているとは確信していません。 これは解決できない宗教的紛争ですか、それともどちらの方向にも客観的なソフトウェアエンジニアリング上の理由がありますか? 注:原則の問題は、特定の言語の実装の詳細に関係なく残っています。たとえば、JavaScriptの場合、引数リストは常に動的であり、パラメーターはargumentsオブジェクトからのローカル変数初期化の構文糖と見なすことができます。それでも、呼び出し元から呼び出し先への情報の受け渡しをキャプチャするため、パラメータ宣言された識別子を「特別」として扱うことができます。

6
オブジェクトが可変である場合、関数型プログラミングのコンテキストで何が問題になる可能性がありますか?
不変オブジェクトのような可変オブジェクトと不変オブジェクトの利点は、共有および書き込み可能な状態が原因で、マルチスレッドプログラミングの問題のトラブルシューティングが非常に困難になることを理解できます。逆に、変更可能なオブジェクトは、毎回新しいコピーを作成するのではなく、オブジェクトのIDを処理するのに役立ちます。そのため、特に大きなオブジェクトのパフォーマンスとメモリ使用量も向上します。 私が理解しようとしていることの1つは、関数型プログラミングのコンテキストで可変オブジェクトを使用すると何が問題になるのかということです。私に言われたポイントの1つのように、異なる順序で関数を呼び出した結果は確定的ではありません。 関数プログラミングで可変オブジェクトを使用すると何がうまくいかないかが非常に明白な実際の具体例を探しています。基本的にそれが悪いのであれば、オブジェクト指向や関数型プログラミングのパラダイムに関係なく悪いのですよね? 私自身の声明自体がこの質問に答えると思います。それでももっと自然に感じられるように、いくつかの例が必要です。 OOは、カプセル化、ポリモーフィズムなどのツールを使用して、依存関係を管理し、より簡単で保守可能なプログラムを作成するのに役立ちます。 関数型プログラミングも、保守可能なコードを促進する同じ動機がありますが、OOツールとテクニックを使用する必要性を排除するスタイルを使用しています。

1
ソース内ビルドとソース外ビルド
私の(主にC ++)開発では、長い間、ソース外ビルドの使用に固執してきました。つまり、私のソースは通常/project/srcディレクトリにあり、ビルド/project/build/bin/releaseは/project/build/bin/debugディレクトリにあります。これを行ったのは、中間ファイルからソースディレクトリをクリーンに保ち、すべてのバイナリを1か所にまとめ、パッケージ化がより簡単になり、クリーニングがより簡単になり、バージョン管理がより簡単になるからです。(私は何かを見逃しましたか?) 現在、ソース内ビルドを使用する(大きな)プロジェクトを継承しています。このタイプの構造の動機は何ですか?その利点は何ですか?(私は、エンジニアリングレベルの理由と個人的な好みのタイプの理由に最も懸念しています。) Lakosの "Large-Scale C ++ Software Design"がそれを考慮に入れてくれることを期待していましたが、そうした場合は見逃しました。

5
長いメソッドのリファクタリング:そのままにするか、メソッドに分離するか、ローカル関数を使用する
私がこのような長い方法を持っているとしましょう: public void SomeLongMethod() { // Some task #1 ... // Some task #2 ... } このメソッドには、個別のメソッドまたはローカル関数に移動する必要がある繰り返し部分はありません。 長いメソッドはコードのにおいだと思っている人はたくさんいます(私を含めて)。また、私は#regionここで(s)を使用するのが好きではありません。なぜこれが悪いのかを説明する非常に人気のある答えがあります。 しかし、このコードをメソッドに分割すると public void SomeLongMethod() { Task1(); Task2(); } private void Task1() { // Some task #1 ... } private void Task2() { // Some task #1 ... } 次の問題が発生します。 単一のメソッドによって内部的に使用される定義でクラス定義スコープを汚染しているため、どこかに文書化する必要がTask1あり、そのTask2内部のみを対象としてSomeLongMethodいます(または、私のコードを読むすべての人がこのアイデアを推測する必要があります)。 単一のSomeLongMethodメソッド内で一度だけ使用されるメソッドの汚染IDEオートコンプリート(Intellisenseなど)。 このメソッドコードをローカル関数に分離すると …

3
解析エラーの場合に詳細情報を提供するTryParseメソッドをどのように設計しますか?
ユーザー入力を解析する場合、例外をスローしてキャッチするのではなく、検証メソッドを使用することをお勧めします。.NET BCLでは、これは、たとえばint.Parse(無効なデータで例外をスローする)とint.TryParse(false無効なデータで戻る)の違いになります。 私は自分でデザインしています Foo.TryParse(string s, out Foo result) メソッドと私は戻り値がわからない。bool.NET独自のTryParseメソッドのように使用することもできますが、エラーのタイプ、つまりに解析できなかった正確な理由について sはわかりませんFoo。(たとえば、s括弧Barが一致していない、文字数が間違っている、対応するがないBazなど) APIのユーザーとして、操作が失敗した理由を通知せずに成功/失敗のブール値を返すだけのメソッドは嫌いです。これにより、推測ゲームのデバッグが可能になり、ライブラリのクライアントにもそれを課したくありません。 私はこの問題の多くの回避策(ステータスコードを返す、エラー文字列を返す、エラーパラメータを出力パラメーターとして追加する)を考えることができますが、それぞれに欠点があり、また、 .NET Frameworkの。 したがって、私の質問は次のとおりです。 (a)例外をスローせずに入力を解析し、(b)単純なtrue / falseブール値よりも詳細なエラー情報を返す.NET Frameworkのメソッドはありますか?
9 c#  .net  api-design 

4
アンビエントコンテキストとコンストラクターインジェクション
データベースのISessionContext、ログ用のILogManager、および別のサービスとの通信に使用されるIServiceを必要とする多くのコアクラスがあります。すべてのコアクラスで使用されるこのクラスに依存性注入を使用したい。 2つの可能な実装があります。3つのクラスすべてのIAmbientContextを受け入れるか、3つのクラスすべてのクラスに注入するコアクラス。 public interface ISessionContext { ... } public class MySessionContext: ISessionContext { ... } public interface ILogManager { } public class MyLogManager: ILogManager { ... } public interface IService { ... } public class MyService: IService { ... } 最初の解決策: public class AmbientContext { private ISessionContext sessionContext; private ILogManager …

5
私が知っていることの道をたどって、正しいコーディングプラクティスを実装しようとするのか、それとも良いコーディングプラクティスから始めて、自分の道をたどろうとするのか?
まず、私は趣味として手続き型プログラミングに慣れていると言いたいのですが、OOPをいくつかの言語で学び、理論を理解しようとしています。練習ではありません。 特にデータベースバックエンドを備えたPHPで構築したいペットプロジェクトがあります(何でもかまいませんでした)。私の主な理由は、アプリが任意のデバイスで使用されることでした。そのため、WebAppは論理的な選択のように思われました。 メンテナンス可能なPHP WebAppを構築するには、OOP、クラス、フレームワーク、ライブラリなどを使用する必要があることを理解しています。これは論理的に聞こえるので、人気のあるものをいくつか試すことにしました。しかし、それらを試してチュートリアルを終わらせようとする週末全体を過ごした後、チュートリアルを私の小さなプロジェクトに適合させようとすることに戸惑い、挫折しました。 私は、主に概念実証のために、別のプログラム(Microsoft Access)でアプリを構築することを決定し、Webパーツを除いて、主な目標をわずか数時間で達成しました。 私の質問は、私は、私が知っているの道をたどる必要がありますされ、その後、正しいコーディングプラクティスを実装しようか、私がすべき始める良いコーディング慣行で、そしてを通じて自分の道をごまかすしようか?このプロジェクトでは、GitHubでオープンソース化したいので、自分のコードを使用および変更している他の人に開放的にしますが、コードの記述が不十分だと、プログラマーを集めて支援するのが難しいことも知っています。

3
ユニットテストを手作業で書くのは例による証明ですか?
JUnitテストの記述は、コードを介した1つの特定のパスを示すことを知っています。 私の仲間の一人がコメントしました: 単体テストを手動で作成することは、例による証明です。 彼は、Quickcheckのようなツールと型を使用したプログラムの動作を推論する機能を備えたHaskellのバックグラウンドから来ていました。 彼の含意は、あなたのコードがテストされていないこの方法で試されない他の入力の組み合わせがたくさんあるということでした。 私の質問は次のとおりです。手動でユニットテストを記述しているかどうかは、例によって証明されますか?

1
DDDのいくつかの概念を実際のコードに適用する方法は?内部の特定の質問
私はDDDを研究しており、現在、実際のコードに概念を適用する方法を見つけるのに苦労しています。私はN層で約10年の経験があるので、私が苦労している理由は、私のメンタルモデルがそのデザインにあまりにも結合しているためです。 私はAsp.NET Webアプリケーションを作成し、単純なドメインであるWeb監視アプリケーションから始めています。要件: ユーザーは、監視する新しいWebアプリを登録できる必要があります。Webアプリにはわかりやすい名前が付けられ、URLをポイントします。 Webアプリは定期的にステータス(オンライン/オフライン)をポーリングします。 Webアプリは定期的に現在のバージョンをポーリングします(Webアプリには、特定のマークアップでシステムバージョンを宣言するファイルである「/version.html」が含まれていることが予想されます)。 私の疑問は主に責任の分割に関係しており、それぞれの適切な場所(検証、ビジネスルールなど)を見つけることです。以下に、コードをいくつか書き、質問と考慮事項を含むコメントを追加しました。 批判し、助言してください。前もって感謝します! ドメインモデル すべてのビジネスルールをカプセル化するようにモデル化されています。 // Encapsulates logic for creating and validating Url's. // Based on "Unbreakable Domain Models", YouTube talk from Mathias Verraes // See https://youtu.be/ZJ63ltuwMaE public class Url: ValueObject { private System.Uri _uri; public string Url => _uri.ToString(); public Url(string url) { _uri …

2
dynamic_castの使用を回避するための適切な設計?
いくつかの調査を行った後、私が頻繁に遭遇する問題を解決する簡単な例を見つけることができないようです。 Squares、Circles、およびその他の形状を作成し、画面に表示し、それらを選択した後でそれらのプロパティを変更して、すべての周囲を計算できる小さなアプリケーションを作成したいとします。 私はこのようなモデルクラスを行います: class AbstractShape { public : typedef enum{ SQUARE = 0, CIRCLE, } SHAPE_TYPE; AbstractShape(SHAPE_TYPE type):m_type(type){} virtual ~AbstractShape(); virtual float computePerimeter() const = 0; SHAPE_TYPE getType() const{return m_type;} protected : const SHAPE_TYPE m_type; }; class Square : public AbstractShape { public: Square():AbstractShape(SQUARE){} ~Square(); void setWidth(float w){m_width = w;} …

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