web-dev-qa-db-ja.com

「開始」、「実行」、または「実行」の方法は良い習慣ですか?

現在、Startメソッドを実装する多くのクラスを持つコードベースに取り組んでいます。これは、私が常に悪い習慣だと考えていた2フェーズ構造のようです。これとコンストラクタの違いはわかりません。

通常のオブジェクト構築の代わりにstartメソッドを使用するのが適切なのはいつですか?

いつコンストラクタを使用したいですか?

編集:私はそれが関連しているとは思いませんが、プログラミング言語はC#です、それはJavaまたはC++に同様に適用できます

30
Dave Hillier

Start()メソッド(Run()Execute()など)は、オブジェクトを構築するコストは低いが、using高いです。例:ベストパス最適化アルゴリズムをカプセル化するクラス。パラメータのセット(X squares by Y squares、suchandsuch評価法)で設定するのは簡単ですが、実行に時間がかかる場合があります。これらのオブジェクトを20個作成する場合は、すべてのオブジェクトが作成されるまで実行を遅らせることができます。これにより、たとえば、オブジェクトの並列化が容易になります。

または、オブジェクトの開始がいつ必要になるかわからない場合に役立ちます。おそらく、ユーザー入力または可能性のリストから選択するロジックに基づいているためです。

もちろん、これはStart()がオブジェクトの便利なメソッドであり、Initialize()メソッドと同等ではないことを前提としています。それがより多くのパラメーターを設定する追加の方法である場合、それは存在すべきではありません。

44
Bobson

Code Complete (および他の多くのソフトウェアエンジニアリングリソース)は、クラスを実際のオブジェクトに一致させることを強調しています。これの根本的な理由は、無形のアイデアにハッキングするよりも、実装していることを正確に把握できる可能性が高くなるためだと思います。

あなたがこの理論のサブスクライバーであれば、Start()メソッドをクラスに追加しても問題はありません。実際のオブジェクトであり、休止状態になっている必要があります。実行されていないときにオブジェクトが存在することが意味をなさない場合(またはオブジェクトが実行されていることを意味がない場合)は、悪い習慣だと思います。

50
Dan Albert

遅延初期化を使用できます。

コンピュータープログラミングでは、遅延初期化は、オブジェクトの作成、値の計算、またはその他のコストのかかるプロセスを、最初に必要になるまで遅らせる戦術です。

これにより、時間結合を回避できます。つまり、クラスのコンシューマは特定のメソッドを特定の順序で呼び出す必要があります。start()を呼び出す必要があります。 1つ目は、クラスが内部でどのように動作するかを知る必要がある方法です。将来的に変更する可能性があるため、これは悪いことです。

最初に必要になるまで、コストのかかる初期化を遅らせます。

例:

public class FooClass{

    private ExpensiveResource resource;
    private CheapResource cheap;

    public  FooClass(String someParameter){
        // constructor: initialize CheapResource cheap 
            // but NOT ExpensiveResource resource
    }

    public ExpensiveResource getExpensiveResource(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource
    }

    public String getExpensiveResourceName(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource.getName();
    }   

    public CheapResource getCheapResource(){
        return this.cheap;
    }

    private initializeExpensiveResource(){
        // do expensive initialization of field "resource"
    }

}

public class Test{
    public static void main (String args[]){

        FooClass foo = new FooClass("some string");
        CheapResource cr = foo.getCheapResource();
        String s = foo.getExpensiveResourceName(); 
          // just now is the expensive resource initialized

    }
}
14