なぜここで継承を気にするのですか?私が見る限り、動作はすべての Chips インスタンスで同じです。その振る舞いは、フレーバーがシリアル番号によって定義されるということです。
シリアル番号がいくつかのことだけを変更する場合は、単純なマップを使用して、シリアル番号に基づいて実行時に動作 (std::function) を挿入または検索できます (なぜ複雑なのか!)。このようにして、シリアル番号マッピングを介して、異なるチップ間で共通の動作が共有されます。
シリアル番号が多くのことを変更する場合、設計が少し逆になっていると思います. その場合、実際に持っているのはチップの構成を定義するシリアル番号であり、設計はそれを反映する必要があります。このような:
class SerialNumber {
public:
// Maybe use a builder along with default values
SerialNumber( .... );
// All getters, no setters.
string getFlavour() const;
private:
string flavour;
// others (package colour, price, promotion, target country etc...)
}
class Chips {
public:
// Do not own the serial number... 'tis shared.
Chips(std::shared_ptr<SerialNumber> poSerial):m_poSerial{poSerial}{}
Chips(int shelf, SerialNumber oSerial):m_poSerial{oSerial}, m_nShelf{shelf}{}
string GetFlavour() {return m_poSerial->getFlavour()};
int GetShelf() {return m_nShelf;}
protected:
std::shared_ptr<SerialNumber> m_poSerial;
int m_nShelf;
}
// stores std::shared_ptr but you could also use one of the shared containers from boost.
Chips pringles{ chipMap.at("standard pringles - sour cream") };
このようにして、製品の一連のシリアル番号を取得すると、製品の動作は変わりません。唯一の変更点は、SerialNumber にカプセル化された「構成」です。Chips
クラスを変更する必要がないことを意味します。とにかく、誰かがクラスを構築する方法を知る必要があります。もちろん、テンプレートベースのインジェクションも可能ですが、コードは正しいタイプをインジェクトする必要があります。
最後のアイデア。ctorSerialNumber
が文字列 (XML や JSON など) を取る場合、管理者タイプの人によって定義された後、実行時にプログラムに構成を読み取らせることができます。これにより、ビジネス ニーズをコードから切り離すことができ、将来を見据えた堅牢な方法となります。
ああ...ハンガリー表記を使用しないことをお勧めします。オブジェクトまたはパラメーターのタイプを変更する場合は、名前も変更する必要があります。さらに悪いことに、それらを変更するのを忘れる可能性があり、他の人が間違った仮定をすることになります. プログラミングに vim/notepad を使用していない限り、IDE はその情報をより明確な方法で提供します。
@ user1158692 - インスタンス化するパーティは、私が提案した設計の 1 つChips
について知る必要があるだけSerialNumber
であり、その提案された設計では、SerialNumber
クラスがクラスを構成するように動作することが規定されていますChips
。その場合、使用者Chips
は親密な関係であるため、SerialNumber について知っている必要があります。クラス間の親密な関係こそが、コンストラクターを介して注入する必要がある理由です。もちろん、必要に応じて代わりにセッターを使用するようにこれを変更するのは非常に簡単ですが、表現された関係のために、これはお勧めできません。
シリアル番号を知らずにチップのインスタンスを作成することが絶対に必要であるとは本当に思えません。これは、クラスの設計に必要な問題ではなく、アプリケーションの問題であると思います。また、このクラスは SerialNumber なしではあまり使用できません。また、SerialNumber なしでクラスの構築を許可した場合は、デフォルト バージョンを使用する必要があります (これらのいずれかを構築する方法をチップスに知らせるか、グローバル参照を使用する必要があります)。多くのチェックでクラスを汚染することになります。
shared_ptr に関する苦情については...所有権のセマンティクスと責任を明確にすることをどのように提案しますか? おそらく生のポインターが解決策になるでしょうが、それは危険で不明確です。shared_ptr は、設計者がポインターを所有しておらず、責任を負わないことを明確に示しています。