我有一个 Position
类,它代表这样的股票头寸:
class Position {
private:
double price_;
double amount_;
double value_;
public:
void SetPrice(double price) {
price_ = price;
}
void SetAmount(double amount) {
amount_ = amount;
}
double GetValue() {
return value_;
}
...
}
3 个成员应满足等式:price * amount = value
。但是每个成员都可以从 setter
更改,保持等式是一个问题。
我有 4 种不同的处理方法:
value_
,并在每次需要时在 getter
中填充值:class Position {
private:
double price_;
double amount_;
// double value_;
...
public:
double GetValue() {
return price_ * amount_;
}
}
优点:
缺点:
total value
中的多个位置和 Portfolio
位置?getter
可能很耗时。value_
class Position {
private:
double price_;
double amount_;
double value_;
...
public:
void SetPrice(double price) {
price_ = price;
value_ = price_ * amount_;
}
void SetAmount(double amount) {
amount_ = amount;
value_ = price_ * amount_;
}
double GetValue() {
return value_;
}
}
优点:
getter
很简单缺点:
setters
都会很耗时,std::optional
或类似的技术,清除 value_
。class Position {
private:
std::optional<double> price_;
std::optional<double> amount_;
std::optional<double> value_;
...
public:
void SetPrice(double price) {
price_ = price;
value_.reset();
}
void SetAmount(double amount) {
amount_ = amount;
value_.reset();
}
double GetValue() {
if (!value_) {
value_ = price_.value() * amount_.value();
}
return value_;
}
}
优点:
setter
比选项 2) 清楚得多缺点:
setters
中还有其他逻辑make
应用程序,将 timestamp
附加到这些成员上。class TimestampData {
private:
double value_
std::time_t time_;
public:
TimestampData& operator=(double value) {
value_ = value;
time_ = std::time(nullptr);
}
}
class Position {
private:
TimestampData price_;
TimestampData amount_;
TimestampData value_;
...
public:
void SetPrice(double price) {
price_ = price;
}
void SetAmount(double amount) {
amount_ = amount;
}
double GetValue() {
if (value_.GetTimestamp() < price_.GetTimestamp()
|| value_.GetTimestamp() < amount_.GetTimestamp()) {
value_ = price_.GetValue() * amount_.GetValue();
}
return value_;
}
}
优点:
setter
与选项 1) 一样清晰缺点:
这只是一个简单的例子,我还有一个类 Portfolio
像这样:
class Portfolio {
private:
double valueOfPositions_
std::map<std::string, Position> positions_
...
}
valueOfPositions_
和 positions_
之间应该有同步机制。
您如何称呼 value_
和 valueOfPositions_
这样的成员?对我来说,他们就像其他成员的 view
成员。
您处理这种情况的最佳做法是什么?
答案 0 :(得分:2)
好的,您在 Position 类中列出了 4 种处理值的方法。我将暂时忽略第 4 个,因为 Timestamp 属性增加了另一层复杂性(您的前 3 个选项也没有 Timestamp 属性)。
在 1st 3 个选项之间,第一个选项(价格和金额的简单设置器,以及价值的 getter 函数)是最干净的,正如您所描述的原因 - 它是如此清晰和简单。 (哪个解决方案在 3 个月后最容易理解?)
经历你描述的缺点:
getter 会很耗时:实际上,价格和数量相乘在计算上非常简单,而且在所有其他解决方案中,您仍然必须进行乘法,只是在不同的点。保持乘法简单和包含(仅在调用 GetValue()
时)意味着您可以控制执行乘法的频率 - 在其他示例中,例如在选项 2 中,每次更新价格或金额时,都会再进行一次乘法运算。
如何处理多个位置和总值:将所有逻辑放在 Portfolio
类中,或者任何包含 Position 对象数组的类 - 初始化一个 GetTotalPositionValue()
函数。在保存 Position 对象的任何数据结构中为多个 Position 对象设置逻辑要干净得多,而不是在 Position 对象本身中设置一些逻辑。
至于添加时间戳,您似乎希望每个 Position 对象都有一个 timestamp
变量,以及其他一些函数,例如GetTotalPositionValueWithinRange()
函数,根据它们的 timestamp
变量获取 Position 对象的子集。 timestamp
似乎也是 Position 对象的一个属性,与价格和金额处于同一级别 - 每个 Position 对象都有一个价格、金额、值和时间戳。
希望能回答您的问题 - 我并不总是最擅长解释设计决策,所以我希望我足够清楚。