私は次の設計哲学を強く信じています。
1> サービスは、データが保存されている場所のできるだけ近くに実装する必要があります。
2> ゲッターとセッターは悪であり、慎重に使用する必要があります。
私はむしろ、ここで 2 つの議論について議論することはせず、それぞれに優位性があると仮定します。
ここに私が現在直面している課題があります。AComputer が A にいくつかのサービスを提供し、A がすべての基本的なデータ メンバーを保持する2 つのクラス (つまりAComputer
と) があります。A
事実:システム設計上、AComputer
内部で結合することはできません。A
私が知っていたのは、計算がデータにとどまるべきであるという私のポイント 1> を壊してしまったことです。
A
からにデータを渡す場合、AComputer
10 個 (およそ) の個々のパラメーターを渡す必要があるため、それを行うための構造を設計することをお勧めします。そうしないと、コンストラクター リストが狂ってしまいます。に格納されているデータのほとんどは、 に格納されてAComputer
いるデータの直接コピーA
です。AComputer
の他の関数AComputer
もこれらの変数を必要とするため、これらのデータを内部に格納することにしました。
これが質問です(APIのメンテナンスと変更を考慮したベストプラクティスを求めています):
1> pass-structure はどこで定義する必要がありますPassData
か?
2> struct に getter/setter を提供する必要がありPassData
ますか?
私の質問を詳細に説明するために、次のようなサンプルコードを提供しました。そこから学ぶことができるように、同じ問題に対処している実際のオープンソース API を見つけることができるのが最善です。
PassData m_data;
class で定義された private を見るとAComputer
、意図的にこれを行っています。言い換えれば、 の基本的な実装を変更した場合、個々の変数または何か他のものにAComputer
置き換えることはできますが、 のインターフェースを壊すことはできません。したがって、この設計では、 struct の getter/setter を提供しません。PassData m_data;
PassData
PassData
ありがとうございました
class AComputer
{
public:
struct PassData
{ // int type just used as an illustration. Real data has different types,
// such as double, data, string, enum, etc.
// Note: they are not exact copies of variables from A but derived from them
int m_v1;
// from m_v1 to m_v10
//...
int m_v10;
};
// it is better to store the passed-in data since other functions also need it.
AComputer(const PassData& pd) : m_data(pd) {}
int GetCombinedValue() const
{ /* This function returns a value based the passed-in struct of pd */ }
private:
PassData m_data;
};
class A
{
private:
int m_i1;
// from m_i1 to m_i10
// ...
int m_i10;
// from m_i11 to m_i20
// ...
int m_i20;
boost::shared_ptr<AComputer> m_pAComputer;
public:
A()
{
AComputer::PassData aData;
// populate aData ...
m_pAComputer = boost::shared_ptr<AComputer>(new AComputer(aData));
}
int GetCombinedValue() const
{
return m_pAComputer->GetCombinedValue();
}
};