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

9
直接オブジェクト構築の代わりにファクトリクラスを使用する必要があるのはなぜですか?
GitHubとCodePlexでいくつかのС#とJavaクラスライブラリプロジェクトの歴史を見てきました。オブジェクトの直接インスタンス化とは対照的に、ファクトリクラスに切り替える傾向が見られます。 なぜファクトリクラスを広範囲に使用する必要があるのですか?クラスのパブリックコンストラクターを呼び出すことで、昔ながらの方法でオブジェクトが作成される、非常に優れたライブラリがあります。最後のコミットで、著者は数千のクラスのすべてのパブリックコンストラクターCreateXXXをすぐに内部に変更し、クラスの内部コンストラクターを呼び出して新しいオブジェクトを返すだけの数千の静的メソッドを持つ1つの巨大なファクトリークラスを作成しました。外部プロジェクトAPIは壊れており、よくできています。 なぜこのような変更が役立つのでしょうか?このようにリファクタリングのポイントは何ですか?パブリッククラスコンストラクターの呼び出しを静的ファクトリメソッド呼び出しに置き換えることの利点は何ですか? いつパブリックコンストラクターを使用する必要があり、いつファクトリーを使用する必要がありますか?

12
オブジェクトのすべての作業をコンストラクターで行う理由はありますか?
これは私のコードでも同僚のコードでもないということで、これを序文にしましょう。数年前、私たちの会社が小さかったとき、私たちには必要なプロジェクトがいくつかありましたが、その能力はありませんでしたので、それらは外部委託されました。今、私は一般的にアウトソーシングや請負業者に対して何もありませんが、彼らが生産したコードベースは大量のWTFです。とはいえ、(ほとんど)動作するので、私が見た外部委託プロジェクトの上位10%にあると思います。 会社の成長に伴い、社内での開発をさらに進めようとしました。この特定のプロジェクトは私の膝に着地したので、私はそれを調べ、掃除し、テストを追加するなどしてきました。 繰り返し見られるパターンが1つありますが、非常に驚​​くほどひどいので、理由があるのではないかと思って、見ないだけです。パターンは、パブリックメソッドやメンバーを持たないオブジェクトであり、オブジェクトのすべての作業を行うパブリックコンストラクターにすぎません。 たとえば、(コードがJavaである場合、それが重要ですが、これがより一般的な質問であることを願っています): public class Foo { private int bar; private String baz; public Foo(File f) { execute(f); } private void execute(File f) { // FTP the file to some hardcoded location, // or parse the file and commit to the database, or whatever } } 疑問に思っているなら、このタイプのコードはしばしば次のように呼ばれます: for(File f …

7
コンストラクタで「new」を使用するのは常に悪いですか?
コンストラクターで「新しい」を使用すること(単純な値オブジェクト以外のオブジェクト)を使用すると、単体テストが不可能になるため(これらのコラボレーターも作成する必要があり、モックできないため)悪い習慣であると読みました。ユニットテストの経験があまりないため、最初に学習するいくつかのルールを収集しようとしています。また、これは使用されている言語に関係なく、一般的に有効なルールですか?

9
C#でのコンストラクターパラメーターの検証-ベストプラクティス
コンストラクターパラメーターの検証のベストプラクティスは何ですか? 単純なC#を想定します。 public class MyClass { public MyClass(string text) { if (String.IsNullOrEmpty(text)) throw new ArgumentException("Text cannot be empty"); // continue with normal construction } } 例外をスローすることは受け入れられますか? 私が遭遇した代替案は、インスタンス化する前の事前検証でした: public class CallingClass { public MyClass MakeMyClass(string text) { if (String.IsNullOrEmpty(text)) { MessageBox.Show("Text cannot be empty"); return null; } else { return new …

5
パラメーターを介して、または戻り値によってC構造体を初期化する必要がありますか?[閉まっている]
私が働いている会社は、次のような初期化関数を使用して、すべてのデータ構造を初期化しています。 //the structure typedef struct{ int a,b,c; } Foo; //the initialize function InitializeFoo(Foo* const foo){ foo->a = x; //derived here based on other data foo->b = y; //derived here based on other data foo->c = z; //derived here based on other data } //initializing the structure Foo foo; InitializeFoo(&foo); 私はこのような構造体を初期化しようとするいくつかのプッシュバックを得ました: …

3
「開始」、「実行」、「実行」の方法は良い習慣ですか?
現在、Startメソッドを実装する多くのクラスを持つコードベースで作業しています。これは私にとって二段階の構成のように思えますが、私は常に悪い習慣だと考えていました。これとコンストラクターの違いはわかりません。 通常のオブジェクト構築の代わりに開始メソッドを使用するのが適切なのはいつですか? コンストラクターを使用するのはいつですか? 編集:私はそれが関連しているとは思わないが、プログラミング言語はC#であり、JavaまたはC ++に等しく適用できる

3
オプションのパラメーターまたはオーバーロードされたコンストラクター
を実装しDelegateCommandていますが、コンストラクターを実装しようとしていたときに、次の2つの設計の選択肢を思いつきました。 1:複数のオーバーロードされたコンストラクターを持つ public DelegateCommand(Action<T> execute) : this(execute, null) { } public DelegateCommand(Action<T> execute, Func<T, bool> canExecute) { this.execute = execute; this.canExecute = canExecute; } 2:オプションのパラメーターを持つコンストラクターを1つだけ持つ public DelegateCommand(Action<T> execute, Func<T, bool> canExecute = null) { this.execute = execute; this.canExecute = canExecute; } どちらを使用するかわからないのは、提案された2つの方法のいずれかにどのような利点/欠点があるかわからないからです。両方とも次のように呼び出すことができます: var command = new DelegateCommand(this.myExecute); var command2 = …

5
コンストラクターでセッターを使用することが一般的なパターンにならなかったのはなぜですか?
アクセサーと修飾子(セッターとゲッター)は、次の3つの主な理由で便利です。 これらは変数へのアクセスを制限します。 たとえば、変数にアクセスすることはできますが、変更することはできません。 パラメータを検証します。 彼らはいくつかの副作用を引き起こす可能性があります。 大学、オンラインコース、チュートリアル、ブログ記事、およびWeb上のコード例はすべて、アクセサと修飾子の重要性について強調しています。最近のコードには「必須」のように感じられます。したがって、以下のコードのように追加の値を提供しなくても、それらを見つけることができます。 public class Cat { private int age; public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } } そうは言っても、実際にパラメーターを検証し、無効な入力が提供された場合に例外をスローしたりブール値を返したりする、より有用な修飾子を見つけることは非常に一般的です: /** * Sets the age for the current cat * @param age an integer with the valid values between …

4
コンストラクターでの正当な「実際の作業」
私はデザインに取り組んでいますが、引き続き障害にぶつかっています。私は特定のクラス(ModelDef)を持っています。これは、本質的にXMLスキーマを解析することで構築された複雑なノードツリーの所有者です(DOMを考えてください)。優れた設計原則(SOLID)に従い、結果のシステムを簡単にテストできるようにします。DIを使用してModelDefのコンストラクターに依存関係を渡すつもりです(テスト中に必要に応じてこれらを簡単に交換できます)。 しかし、私が苦労しているのは、ノードツリーの作成です。このツリーは、個別にテストする必要のない単純な「値」オブジェクトで完全に構成されます。(ただし、これらのオブジェクトの作成を支援するために、Abstract FactoryをModelDefに渡すことができます。) しかし、私は、コンストラクターが実際の作業を行うべきではないことを読み続けています(例:Flaw:Constructor does Real Work)。「実際の作業」とは、後でテストのためにスタブアウトする可能性のある重い依存オブジェクトを構築することを意味する場合、これは私にとって完全に理にかなっています。(これらはDI経由で渡される必要があります。) しかし、このノードツリーなどの軽量の値オブジェクトはどうでしょうか。ツリーはどこかに作成する必要がありますよね?ModelDefのコンストラクター(buildNodeTree()メソッドなどを使用)を使用しないのはなぜですか? ModelDefの外でノードツリーを作成してから(コンストラクターDIを介して)渡したいとは思いません。スキーマを解析してノードツリーを作成するには、かなりの量の複雑なコードが必要です。 。私はそれを「グルー」コードに委ねたくありません(これは比較的簡単なはずで、おそらく直接テストされません)。 ノードツリーを作成するためのコードを別の「ビルダー」オブジェクトに入れることを考えましたが、実際にはビルダーパターン(テレスコープの排除に関心があると思われる)と一致しないため、「ビルダー」と呼ぶことをためらいます。コンストラクター)。ただし、別の名前(NodeTreeConstructorなど)を呼び出したとしても、ModelDefコンストラクターがノードツリーを構築するのを避けるために、ちょっとしたハックのように感じます。どこかに構築する必要があります。なぜそれを所有しようとしているオブジェクトではないのですか?

5
コンストラクタをどのように分解できますか?
私にはEnemyクラスがあり、コンストラクタは次のようになります。 public Enemy(String name, float width, float height, Vector2 position, float speed, int maxHp, int attackDamage, int defense... etc.){} コンストラクターには非常に多くのパラメーターがあるため、これは悪いように見えますが、Enemyインスタンスを作成するときは、これらすべてを指定する必要があります。また、これらの属性をEnemyクラスに含めて、それらのリストを反復処理し、これらのパラメーターを取得/設定できるようにします。EnemyをEnemyB、EnemyAにサブクラス化して、maxHpなどの特定の属性をハードコーディングすることを考えていましたが、Enemyのリスト(EnemyA、EnemyB、およびEnemyC's)。 私はただきれいにコーディングする方法を学ぼうとしています。違いがあれば、Java / C ++ / C#で作業しています。正しい方向の任意のポイントが高く評価されています。

3
多数のパラメーターとビルダーパターンを持つコンストラクター
クラスに多くのパラメーター(たとえば4個以上)を持つコンストラクターがある場合は、おそらくコードの匂いであることがよく知られています。クラスがSRPを満たすかどうかを再検討する必要があります。 しかし、10個以上のパラメーターに依存するオブジェクトをビルドし、オブジェクトを作成し、最終的にBuilderパターンを使用してこれらすべてのパラメーターを設定するとどうなりますか?Person個人情報、仕事情報、友人情報、興味情報、教育情報などを含むタイプオブジェクトを作成するとします。これは既に良いことですが、どういうわけか同じ4つ以上のパラメーターを設定していますか?なぜこの2つのケースは同じと見なされないのですか?

3
コンストラクターの複雑さ
私は、コンストラクターがどれだけの作業を行えるかについて同僚と議論しています。内部に別のオブジェクトAを必要とするクラスBがあります。オブジェクトAは、クラスBがその仕事をするために必要な数少ないメンバーの1つです。そのパブリックメソッドはすべて内部オブジェクトAに依存します。オブジェクトAに関する情報はDBに格納されているので、コンストラクターでDBを検索して検証および取得を試みます。私の同僚は、コンストラクターがコンストラクターのパラメーターをキャプチャする以外に多くの作業を行うべきではないと指摘しました。コンストラクターへの入力を使用してオブジェクトAが見つからない場合、すべてのパブリックメソッドはとにかく失敗するため、インスタンスを作成して後で失敗させるのではなく、実際にはコンストラクターで早期にスローする方がよいと主張しました。 他の人はどう思いますか?それが違いを生む場合は、C#を使用しています。 読書オブジェクトのすべての作業をコンストラクターで行う理由はありますか?ユーザーがコンストラクタに間違った値を渡した場合、そのパブリックメソッドを使用できないため、DBにアクセスしてオブジェクトAを取得することは「オブジェクトを使用可能にするために必要な他の初期化」の一部です。 コンストラクターは、オブジェクトのフィールドをインスタンス化し、オブジェクトを使用可能にするために必要な他の初期化を行う必要があります。これは一般に、コンストラクターが小さいことを意味しますが、これがかなりの量の作業になるシナリオがあります。
18 c#  constructors 

1
デフォルトのコンストラクタを使用できなくすることは問題ありませんか?
デフォルトのコンストラクターについて具体的に尋ねる コンストラクターがオブジェクトのすべてのデータを初期化する場合、適切な初期化なしでは使用できないクラスを作成すると、デフォルトのコンストラクターが役に立たなくなるわけではありませんか?考慮してください: // A class for handling lines in a CSV file class CSV_Entry { private: unsigned num_entries; std::string string_version; std::vector<std::string> vector_version; ...etc public: CSV_Entry(); CSV_Entry(const std::string& src_line); // returns a vector copy of the original entry std::vector<std::string> get_vector_snapshot(); } int main( void ) { ...etc CSV_Entry example = CSV_Entry(); …

3
どうすれば引数の数を低く保ちながら、サードパーティの依存関係を分離したままにできますか?
サードパーティのライブラリを使用しています。彼らは私たちの意図と目的のために、おそらく次のように実装されたPOJOを渡します: public class OurData { private String foo; private String bar; private String baz; private String quux; // A lot more than this // IMPORTANT: NOTE THAT THIS IS A PACKAGE PRIVATE CONSTRUCTOR OurData(/* I don't know what they do */) { // some stuff } public String getFoo() { …

2
ドメインオブジェクトの作成をテストする単体テスト
次のような単体テストがあります。 [Test] public void Should_create_person() { Assert.DoesNotThrow(() => new Person(Guid.NewGuid(), new DateTime(1972, 01, 01)); } ここでPersonオブジェクトが作成された、つまり検証が失敗しないと断言しています。たとえば、Guidがnullの場合、または生年月日が1900年1月1日より前の場合、検証は失敗し、例外がスローされます(テストが失敗したことを意味します)。 コンストラクターは次のようになります。 public Person(Id id, DateTime dateOfBirth) : base(id) { if (dateOfBirth == null) throw new ArgumentNullException("Date of Birth"); elseif (dateOfBith < new DateTime(1900,01,01) throw new ArgumentException("Date of Birth"); DateOfBirth = dateOfBirth; } これはテストのための良いアイデアですか? 注:ドメインモデルの単体テストに古典的なアプローチを採用している場合は、それが何らかの意味を持っています。

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