在一次访谈中,我被问到了以下面向对象的系统设计问题。
有多种设备,如回声显示、回声点、回波标签、智能微波、火电棒等。
因此,基本上这些是3类,如-扬声器/屏幕显示/扬声器和屏幕显示,有两类,如-供电/电池供应。可以在任何这些设备上进行查询,比如打印状态。以下是每个设备的可能输出-
假设有内置的在屏幕上讲话和打印的类。如果我们将字符串传递给这些类对象,它们将执行各自的工作。
现在编写4-5个类来建模这个场景。
设计应该是可扩展的,如果明天任何新的设备都有一个新的组合,那么它就可以实现,而无需创建任何新的类。因此,您不应该为每个设备创建类。
这是我的面向对象的解决方案,但面试官对此并不满意,尤其是vector<Output*> outputs。他建议使用一些设计模式,而不是矢量。你能想出更好的解决办法吗?
class Output {
public:
virtual void print(string);
};
class Display : public Output {
DisplayScreen obj;
public:
void print(string str) { obj.print(str); }
};
class Speaker : public Output {
Audio obj;
public:
void print(string str) { obj.print(str); }
};
class PowerSupply {
public :
virtual string get_status();
};
class BatteryPower : PowerSupply {
bool isCharging;
int chargeLevel;
public :
string get_status();
};
class ElectricPower : PowerSupply {
bool isCharging;
public :
string get_status();
};
class Device {
vector<Output*> outputs;//I used vector because Echo show has both display and speaker
PowerSupply powersupply;
Device(vector<Output> &outputs, PowerSupply powersupply) {
this->outputs = outputs;
this->powersupply = powersupply;
}
};发布于 2021-12-22 14:46:45
vector<Output>不允许继承,因为它直接存储Output的指针或引用。如果将Display或Speaker存储在向量中,则为sliced。
由于每个设备的输出都是唯一的,所以我会将其作为唯一指针的向量:
std::vector<std::unique_ptr<Output>> outputs;发布于 2021-12-27 10:11:47
我不认为面试官要求使用某种设计模式是有任何建设性的。设计模式是完成某事的工具;没有目标,设计模式就毫无意义。相反,他可能会说:“我们预计将不得不用最小的偏差建造许多类似的设备。你将如何做到这一点?”在“现在标签的随机设计模式和我们是黄金”。
除了技术问题,John Kugelman answered here。我认为有几种设计模式,你可以使用,而不仅仅是传递一个矢量的设备和电源。我头顶上的一些例子:
工厂模式
研究关键词:工厂模式
class DotFactory
{
DotFactory(/*maybe you need parameters*/);
Device* getDevice(/*more parameters e.g. speaker count*/);
}建造者模式
研究关键词:构建器模式
根据复杂性和用例,您可以将设备构建器集成到设备中。为了简单起见,我是这样做的。
class Device
{
// Your stuff
vector<Output*> outputs;
PowerSupply powersupply;
Device(vector<Output*> &outputs, PowerSupply *powersupply);
// Builder functions
bool addPowerSupply(PowerSupply*);
bool addOutput(Output*);
// If outside your Device class also integrate:
Device* getBuiltDevice();
};更多的模式和组合(我本来想出一个以上的。也许有人可以编辑更多。)
单例设备列表(大多数情况下是反模式的)
根据使用程序的不同,您也可以拥有任何东西(方法、容器、类等)。持有您的预定义‘设备’,如果您只需要每个应用程序一个。
发布于 2021-12-30 22:07:19
我建议介绍以下5门课程:
用于电源状态的
的实际抽象)
我用structs代替了类来缩短符号。通过依赖注入函子获取电池电平。C++20有std::format,也许您的编译器也有。
// Assuming Screen and Speaker are provided in a common interface
struct OutputDevice{
virtual void publish(std::string const & output) = 0;
virtual ~OutputDevice()=default;
}
using OutputDevice_sp = std::shared_ptr<OutputDevice>;
struct Screen : OutputDevice{
void publish(std::string const & output) override {
// ...
};
};
struct Speaker : OutputDevice{
void publish(std::string const & output) override {
// ...
};
};
/// Here goes the actual implementation
struct PowerStatusProvider{
virtual std::string to_string(bool Connected) const = 0;
virtual ~PowerStatusProvider()=default;
};
struct BatteryStatus : PowerStatusProvider{
BatteryStatus(std::function<double()> BatteryLevelProvider)
: mBatteryLevelProvider(BatteryLevelProvider){}
std::string to_string(bool Connected) const override
{
if (Connected)
return "Battery is charging";
else
return std::format("Battery is not charging and battery level is {}%",mBatteryLevelProvider());
}
private:
std::function<double()> mBatteryLevelProvider;
};
struct WiredStatus : PowerStatusProvider{
std::string to_string(bool Connected) const override
{
if (Connected)
return "Device connected";
else
return "Device not connected";
}
};
struct OutputHandler{
OutputHandler(std::vector<OutputDevice_sp> Outputs)
: mOutputs(Outputs) {}
void handle(std::string const & output) const {
for (auto &&output : mOutputs) {
output->publish(output);
}
}
private:
std::vector<OutputDevice_sp> mOutputs;
};
using PowerStatusProvider_sp = std::shared_ptr<PowerStatusProvider>;
using OutputHandler_sp = std::shared_ptr<OutputHandler>;
struct Device{
struct Device(std::string Name, PowerStatusProvider_sp PSP, OutputHandler_sp OH)
: mName(Name)
, mPSP(PSP)
, mOH(OH)
{}
void update_status() const{
mOH->handle(mPSP->to_string());
}
private:
std::string mName;
std::shared_ptr<PowerStatusProvider> mPSP;
std::shared_ptr<OutputHandler> mOH;
};https://stackoverflow.com/questions/70450543
复制相似问题