ソフトウェア工学

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

6
TDDの使用時に機能または機能を削除する方法
TDDに関するテキストでは、リファクタリングのステップ中に「重複の削除」または「読みやすさの向上」についてよく読みます。しかし、未使用の関数を削除する理由は何ですか? たとえばC、メソッドa()とを持つクラスがあるとしましょうb()。今私はそれにf()追いやられる方法を持つことが良いと思うC。実際、定義/記述された単体テストを除くf()すべての呼び出しを置き換えます。これはもう必要ありません-テストを除いて。b()b() 削除してb()、それを使用したすべてのテストを削除するだけでいいですか?その部分は「読みやすさの改善」ですか?

4
関数型プログラミングの値を「記憶」する
関数型プログラミングを学ぶというタスクを自分で引き受けることにしました。これまでのところ、それは爆発でした、そして、私はそれがそうであったように「光を見ました」。残念ながら、私は質問を跳ね返すことができる機能的なプログラマーを実際には知りません。Stack Exchangeの紹介。 Web /ソフトウェア開発コースを受講していますが、講師は関数型プログラミングに精通していません。彼は私がそれを使って大丈夫であり、彼が私のコードをよりよく読むことができるように彼がそれがどのように機能するかを理解するのを助けるように私に尋ねた。 これを行う最善の方法は、値を累乗するなどの単純な数学関数を示すことだと判断しました。理論的には、事前に作成された関数を使用して簡単にそれを行うことができますが、これは例の目的に反します。 とにかく、私は値を保持する方法を理解するのに少し苦労しています。これは関数型プログラミングなので、変数を変更することはできません。これを命令的にコーディングすると、次のようになります。 (以下はすべて擬似コードです) f(x,y) { int z = x; for(int i = 0, i < y; i++){ x = x * z; } return x; } 関数型プログラミングでは、確信が持てませんでした。これは私が思いついたものです: f(x,y,z){ if z == 'null', f(x,y,x); else if y > 1, f(x*z,y-1,z); else return x; } これは正解?zどちらの場合も値を保持する必要がありますが、関数プログラミングでこれを行う方法がわかりませんでした。理論的には、私がやった方法はうまくいきますが、それが「正しい」かどうかはわかりませんでした。それを行うより良い方法はありますか?

11
コーディングのベストプラクティスを常に使用する必要があります[終了]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 閉じた3年前。 ソフトウェアをコーディングする場合、構築するアプリケーションに関して、アーキテクチャは常にベストプラクティスまたは実践的プラクティスのどちらである必要がありますか? 5年間存続する可能性のある2ページのWebアプリケーションを構築し、その5年間で2つの機能拡張を行う場合、依存性注入、デザインパターン、ビューモデルを備えたモデルビューコントローラーなどでコーディングする必要があります

3
テストと製品コードの間で定数を複製しますか?
テストと実際のコード間でデータを複製するのは良いですか、悪いですか?たとえば、FooSaver特定の名前のファイルを特定のディレクトリに保存するPythonクラスがあるとします。 class FooSaver(object): def __init__(self, out_dir): self.out_dir = out_dir def _save_foo_named(self, type_, name): to_save = None if type_ == FOOTYPE_A: to_save = make_footype_a() elif type == FOOTYPE_B: to_save = make_footype_b() # etc, repeated with open(self.out_dir + name, "w") as f: f.write(str(to_save)) def save_type_a(self): self._save_foo_named(a, "a.foo_file") def save_type_b(self): self._save_foo_named(b, "b.foo_file") 私のテストでは、これらのファイルがすべて作成されたことを確認したいので、次のように言いたいと思います。 …

5
なぜ型がそのビルダーと結合されるのでしょうか?
私は最近、Code Reviewで私のJavaの回答を削除しました。 private Person(PersonBuilder builder) { やめる。赤旗。PersonBuilderはPersonを構築します。それは人について知っています。PersonクラスはPersonBuilderについて何も知らないはずです-それは単なる不変の型です。ここで、Aに依存するBに依存するAに依存する循環カップリングを作成しました。 Personはパラメータを取得するだけです。構築せずにPersonを作成するクライアントは、それを実行できる必要があります。 私は下票で平手打ちされ、それを(引用して)赤旗と言った、なぜ?ここでの実装は、Joshua Blochが彼の「Effective Java」本(アイテム#2)で示したものと同じ形をしています。 したがって、Javaでビルダーパターンを実装する正しい方法は、ビルダーをネスト型にし(これはこの質問の目的ではありません)、製品を作成することです(ビルドされているオブジェクトのクラス)このように、ビルダーに依存します: private StreetMap(Builder builder) { // Required parameters origin = builder.origin; destination = builder.destination; // Optional parameters waterColor = builder.waterColor; landColor = builder.landColor; highTrafficColor = builder.highTrafficColor; mediumTrafficColor = builder.mediumTrafficColor; lowTrafficColor = builder.lowTrafficColor; } https://en.wikipedia.org/wiki/Builder_pattern#Java_example 同じBuilderパターンの同じWikipediaページには、C#の実装が大きく異なります(そして、はるかに柔軟です)。 //Represents a product created …

4
フロントエンドとバックエンド間のトランスポートとしてフラットファイルとデータベース/ APIを使用する
数人の開発者の間で議論がかなり白熱したアプリケーションがあります。 基本的に、Webレイヤーとバックエンドレイヤーに分割されます。Webレイヤーは単純なWebフォームによって情報を収集し、このデータをJSONドキュメント(文字列は.jsonファイル)としてバックエンドが使用する監視フォルダーに格納します。バックエンドは数秒ごとにこのフォルダーをポーリングし、ファイルを取得して、その機能を実行します。 ファイル自体は非常にシンプル(つまり、すべての文字列データ、ネストなし)で、最大で1〜2kで、システムはほとんどの時間をアイドル状態にします(ただし、最大100メッセージまでバーストします)。バックエンド処理ステップは、メッセージごとに約10分かかります。 議論は、ある開発者がファイルシステムをメッセージングレイヤーとして使用することは悪いソリューションであると示唆した場合、リレーショナルデータベース(MySQL)、noSQLデータベース(Redis)、またはプレーンREST APIコールなどを代わりに使用する必要がある場合に出てきます。 Redisは、キュー内のメッセージ処理のために組織内の他の場所で使用されることに注意してください。 私が聞いた議論は次のように分類されます フラットファイルを支持して: フラットファイルは、他のソリューションよりも信頼性が高くなります。ファイルは、「監視」フォルダーから、取得後に「処理」フォルダーに、最後に「完了」フォルダーに移動するためです。とにかく他のものを壊すような非常に低レベルのバグがない限り、メッセージが消えるリスクはありません。 フラットファイルを理解するには、それほど高度な技術は必要ありません- catそれだけです。書き込むクエリはありません。誤ってメッセージをキューからポップして、メッセージが永遠に消えてしまうリスクはありません。 ファイル管理コードは、すべての言語の標準ライブラリの一部であるため、プログラミングの観点からデータベースAPIよりも簡単です。これにより、コードベースの全体的な複雑さと、導入する必要のあるサードパーティコードの量が削減されます。 YAGNI原則州フラットファイルが今うまく動作することを、それを残して、より複雑なソリューションに変更するための実証され必要はありません。 データベースを支持して: ファイルがいっぱいのディレクトリよりもデータベースを拡張する方が簡単です フラットファイルには、誰かが「完了」ファイルを「監視」ディレクトリにコピーして戻すリスクがあります。このアプリケーションの性質(仮想マシン管理)により、これにより壊滅的なデータ損失が発生する可能性があります。 T / Sにより高度な技術を必要とするアプリは、教育を受けていないスタッフが物事を突くだけで何かを台無しにする可能性が低いことを意味します。 特にRedisなどのDB接続コードは、少なくとも標準ライブラリファイル管理機能と同じくらい堅牢です。 DB接続コードは、ファイル操作よりもレベルが高いため、開発者の観点からは(機能的にではないにしても)明らかに単純です。 私が見ることができることから、両方の開発者は多くの有効なポイントを持っています。 これら2人のプロファイル開発者、またはプロデータベース開発者のうち、どちらがソフトウェアエンジニアリングのベストプラクティスに沿っているのでしょうか?

3
Java / Linuxスタックが「リアルタイム」に失敗する理由は何ですか?
開発者は、Javaが「リアルタイムを実行できない」、つまりLinuxで実行されているJavaアプリがRIOT-OSで実行されているものなどの確定的なリアルタイムシステムの要件を満たせないことを言及することをよく耳にします。 理由を理解しようとしています。私のSWAGによると、これはおそらくJavaのガベージコレクターによるものと思われます。Javaガベージコレクターはいつでも実行でき、システムを完全に一時停止できます。また、いわゆる「一時停止GC」はありますが、必ずしも広告を信じているわけではありません。また、趣味のプロジェクトに分岐するためのJVMインスタンスあたり$ 80Kもありません。 Linuxでのドローンソフトウェアの実行に関するこの記事も読んでいました。その記事で、著者はLinuxがドローンを車に衝突させそうになったシナリオについて説明しています。 Piで低レベル制御ループ(PID)を実行することを選択した後、ハードレッスンを学びました-巧妙にしようとして、デバッグのためにループの中央にログ書き込みを配置することを決めました-クワッドは最初はうまく飛んでいましたが、Linuxは決定しました1つのログエントリを書き込むのに2秒かかり、クワッドは私の車にほとんどクラッシュしました! その著者はドローンソフトウェアをC ++で作成しましたが、Linux上で実行されているJavaアプリが同じ運命をたどる可能性が非常に高いと思います。 ウィキペディアによると: 操作の全体的な正確さが、その論理的な正確さだけでなく、実行される時間にも依存する場合、システムはリアルタイムであると言われます。 だから、私には、この手段は、「総正しさを論理的正当性と適時性を必要とする場合は、リアルタイムではありません。」 Javaアプリを書いて超高性能になり、いわば「レモンを絞る」ようになりましたが、それを(Javaで)速く書くことはできませんでした。 全体として、私の質問は次のとおりです。Linuxを実行しているJavaアプリが「リアルタイムアプリ」にならない理由のすべて/ほとんどの理由を説明してくれる人を探しています。つまり、Java / Linuxスタック上の「タイムリー」であることを妨げ、したがって「完全に正しい」ことを妨げるすべてのカテゴリは何ですか?前述のように、GCとLinuxのログフラッシュは実行を一時停止する可能性がありますが、Javaアプリ自体の外部には、タイミングやパフォーマンスが低下し、ハードデッドラインの制約を満たすものがもっとあるはずです。彼らは何ですか?
20 java  linux  real-time 

8
不変オブジェクトで引数の検証とフィールドの初期化をテストする簡単な方法はありますか?
私のドメインは、次のような多くの単純な不変のクラスで構成されています。 public class Person { public string FullName { get; } public string NameAtBirth { get; } public string TaxId { get; } public PhoneNumber PhoneNumber { get; } public Address Address { get; } public Person( string fullName, string nameAtBirth, string taxId, PhoneNumber phoneNumber, Address address) { if (fullName …
20 c#  unit-testing 

5
フォールバックのある特別なケースは、リスコフ代替原理に違反しますか?
FooInterface次のシグネチャを持つインターフェイスがあるとします。 interface FooInterface { public function doSomething(SomethingInterface something); } そして、ConcreteFooそのインターフェースを実装する具体的なクラス: class ConcreteFoo implements FooInterface { public function doSomething(SomethingInterface something) { } } ConcreteFoo::doSomething()特別なタイプのSomethingInterfaceオブジェクトが渡された場合、ユニークな何かをしたいと思います(と呼ばれますSpecialSomething)。 メソッドの前提条件を強化するか、新しい例外をスローする場合、それは間違いなくLSP違反ですが、SpecialSomething汎用SomethingInterfaceオブジェクトのフォールバックを提供しながらオブジェクトを特別にケースに入れた場合でもLSP違反になりますか?何かのようなもの: class ConcreteFoo implements FooInterface { public function doSomething(SomethingInterface something) { if (something instanceof SpecialSomething) { // Do SpecialSomething magic } else { // Do generic SomethingInterface …

3
順序付けされた情報をリレーショナルデータベースに保存する方法
注文した情報をリレーショナルデータベースに適切に保存する方法を理解しようとしています。 例: 曲で構成されるプレイリストがあるとします。リレーショナルデータベース内には、Playlistsいくつかのメタデータ(名前、作成者など)を含むの。また、私はと呼ばれるテーブルを持っSongs含む、playlist_id曲固有の情報(名前、アーティスト、期間など)だけでなく、。 デフォルトでは、新しい曲がプレイリストに追加されると、最後に追加されます。Song-ID(昇順)で注文する場合、注文は追加の順序になります。しかし、ユーザーがプレイリストの曲を並べ替えることができるとしたらどうでしょうか? いくつかのアイデアを思いつきました。それぞれに長所と短所があります。 と呼ばれる列orderは、。整数です。曲を移動すると、その変更を反映するために、古い位置と新しい位置の間のすべての曲の順序が変更されます。これの欠点は、曲を移動するたびに多くのクエリを実行する必要があり、移動アルゴリズムが他のオプションほど簡単ではないことです。 orderという10進数の列(NUMERIC)。曲を移動すると、隣接する2つの数字の間に浮動小数点値が割り当てられます。欠点:10進数フィールドはより多くのスペースを必要とし、数回変更するたびに範囲を再分散するように注意しない限り、精度が不足する可能性があります。 別の方法はprevious、next他の曲を参照するフィールドとフィールドを持つことです。(または、現在、プレイリストの最初の曲、最後の曲の場合はNULLです。基本的には、リンクリストを作成します)。欠点:「リストでX番目の曲を見つける」などのクエリは、一定時間ではなく、線形時間になります。 これらの手順のうち、実際に最もよく使用されるのはどれですか?これらの手順のうち、中規模から大規模のデータベースで最も速いのはどれですか?これを実現する他の方法はありますか? 編集:簡単にするため、この例では、ソングは1つのプレイリストにのみ属します(多対1の関係)。もちろん、ジャンクションテーブルを使用して、song⟷playlistを多対多の関係にすることもできます(そして、そのテーブルに上記の戦略の1つを適用します)。

1
<の違いは何ですか?Foo>および<Foo>を拡張します
私は、違いについて誤解があるようだ&lt;Foo&gt;とし&lt;? extends Foo&gt;。私の理解から、もしあれば ArrayList&lt;Foo&gt; foos = new ArrayList&lt;&gt;(); これは、タイプのオブジェクトFooをこの配列リストに追加できることを示します。のサブクラスFooもtype Fooであるため、次のようにエラーなしで追加できます。 ArrayList&lt;Foo&gt; foos = new ArrayList&lt;&gt;(); foos.add(new Foo()); foos.add(new Bar()); ここでBar extends Foo。 さて、私が定義されていたと言うfoosと ArrayList&lt;? extends Foo&gt; foos = new ArrayList&lt;&gt;(); 私の現在の理解はこれが表現するということsome unknown type that extends Fooです。これは、サブクラスであるオブジェクトFooをこのリストに追加できることを意味します。差がないことを意味ArrayList&lt;Foo&gt;してArrayList&lt;? extends Foo&gt;。 これをテストするために、次のコードを記述しようとしました ArrayList&lt;? extends Foo&gt; subFoos = new ArrayList&lt;&gt;(); subFoos.add(new Foo()); subFoos.add(new Bar()); …
20 java  generics 

1
あなたのコードで複数形タンタムを扱うための標準は何ですか?[閉まっている]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 4年前に閉鎖されました。 複数形と単数形が同じ変数を使用する場合、どのように名前を付けますか?そこに標準はありますか? 例えば: Series[] series // Plural Series series // Singular 詳細: 具体的に言うと、シリーズのコレクションは(JSONフォーマットのため)シリーズと呼ばれる必要がありますSeries s。コレクションに追加される単数形のシリーズに名前を付けることを検討してください。 次のように: List&lt;Series&gt; series = new List&lt;Series&gt;(); Series s; while (someBool) { s = new Series(); s.Name = "Name"; while (anotherBool) { s.AddValue(someValue); } series.Add(s); }

2
Swiftがセミコロンを必要としないのはなぜですか?[閉まっている]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 4年前に閉鎖されました。 私は通常c#またはObjective-Cのいずれかでコーディングし、最近Appleの新しいプログラミング言語であるSwiftを習得しました。 私が最初に気づいたのは、Swiftで行を終了するためにセミコロンを追加する必要がないことですが、少なくともテストしたことからすれば、コンパイラに干渉しません。 私が書くとき: int someNumber = 0; Objective-Cでは、セミコロンはプログラムに、行が終わって次の行に落ちないことを伝えます。 Swiftでは、変数を宣言できます var someNumber:Int = 5 セミコロンを追加しないと、システムはこれが行の終わりであることを認識します。 一部の言語でこれを行うことができ、他の言語ではできないことは何ですか?最後にセミコロンを追加する均一なシステムを維持してみませんか?


1
Mavenに似たHaskellビルドおよびアーティファクト環境
私は以前からJava開発者でしたが、最近、Haskellチームに参加しました。Javaの世界では、複数のチームが取り組んでいる大規模なプロジェクトがある場合、Mavenなどのアーティファクトサーバーを使用して開発を容易にし、スピードアップするのが一般的なアプローチです。Ant、Maven、Gradleなどの多数のビルドツールを使用してプロジェクトをビルドし、jarファイルをアーティファクトサーバーにアップロードして、チームの残りのメンバーが簡単に使用できます。したがって、プロジェクトをより小さなサブプロジェクトに分割することにより、ビルド時間も大幅に短縮されます。 Haskell側ではcabal、プロジェクトのビルドに使用しています。このプロジェクトは、最適化なしでビルドするのに約10〜15分かかります。コンパイラーの最適化がオンになっている場合、数時間かかりますが、これは苦痛です。 ここでJavaで行うのと同じことをどのように行うことができるのでしょうか。パッケージ(ライブラリ)のバイナリをコンパイルしてアーティファクトサーバーにアップロードし、ビルド時にビルド済みのバイナリを使用する簡単な方法はありますか?Haskellは(Javaのバイトコードではなく)マシンコードを生成するため、互換性の問題があるかもしれませんが、アーティファクトサーバーに格納されているアーキテクチャ/ OSごとに異なるバイナリを使用できる可能性があります。

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