2016-12-05 8 views
2

私は現在、ファクトリデザインパターンを実装しようとしていますが、これはC++でどのようにして行われるのか多少混乱します。私はthisウェブページを参照しています。名前空間の代わりに静的なクラス関数を使用するのはいつですか?

したがって、それらのWebページでは、ComputerFactoryというファクトリクラスを定義する例を示しています。このクラスには静的な単一のNewComputerメソッドがあります。

class ComputerFactory 
{ 
public: 
    static Computer *NewComputer(const std::string &description) 
    { 
     if(description == "laptop") 
      return new Laptop; 
     if(description == "desktop") 
      return new Desktop; 
     return NULL; 
    } 
}; 

NewComputerが静的であるという事実は、それがComputerFactoryの単一のインスタンスに関連付けられていないことを意味します。したがって、あなたのコードからこのメソッドを呼び出すことができます。

ComputerFactor::NewComputer("description"); 

これはなぜクラス内でラップする必要があるのか​​不思議です。それは、静的だと本当に任意のクラスに関連付けされることを意味しない、それはだから私の質問に

namespace ComputerFactory 
{ 
    static Computer *NewComputer(const std::string &description) 
    { 
     if(description == "laptop") 
      return new Laptop; 
     if(description == "desktop") 
      return new Desktop; 
     return NULL; 
    } 
} 

のような何かをするより理にかなっているので:

  • は、私は、有効な記述、名前空間機能です代替?
  • 静的メソッドのみを持つクラスを定義することは理にかなっていますか?名前空間を使用する方が理にかなっているようです。

静的メソッド(静的な「現在のクラスはいくつあるか」など)が必要な場合がありますが、これは必要な状況には見えません。何かご意見は?

編集:私はちょうど考えを持っていました。私が挙げた例は、「典型的な」ファクトリメソッドではありません。実際には、ファクトリ関数はより複雑で、他の関数(プライベートクラスメソッド)を呼び出す必要があります。この場合、サブファンクションにアクセスできるように、ファクトリをクラスにラップするのは完全な意味を持ちます。なぜファクトリメソッドがクラスにラップされるのですか?

答えて

2

私が有効な代替方法を説明しましたか?

はい

それは今までにのみ静的メソッドを持つクラスを定義するために意味をなすだろうか?名前空間を使用する方が理にかなっているようです。彼らはnamespaceにするため

方法は、多くのクラスで利用することができるユーティリティメソッドがある場合、それはより多くの意味になるだろう。

メソッドがクラス固有のものである場合は、クラス自体の中にstaticを作成してください。これによりカプセル化が改善されます。

0

私が有効な代替方法として説明した名前空間機能はありますか?

はい。

静的メソッドのみを持つクラスを定義することは意味がありますか?名前空間を使用する方が理にかなっているようです。

名前空間ではできないクラスでできることがあります。
匿名の名前空間を使用して同様のことを行うことはできますが、実際にはうまくいきませんが、プライベートメンバーを利用するためには、

もう1つの関連する例は、templatize名前空間であり、これは非常に厄介なことができないということです。あなたはそれをあなたが名前空間を使用している場合、関数テンプレートを定義することができ、他の点では

namespace N { 
    template<typename T> 
    T f() { return T(); } 

    // Other function template 
} 

// ... 

N::f<int>(); 

template<typename T> 
struct S { 
    static T f() { return T(); } 
    // Other member functions 
}; 

// ... 

using MyS = S<int>; 
MyS::f(); 

これはテンプレートで発生します:例として
は、このクラスで発生しますどんな状況においても最高の解決策にはなり得ませんでした。
さらに、エイリアスはクラスと同じように作成することはできません。したがって、呼び出し場所の型について明示的に指定する必要があります。エラーが発生しやすく、リファクタリングが難しい場合があります。

関連する問題