我有一个用户输入飞机操作的程序。用户可以根据需要选择任意数量的操作(保持,直线,着陆等)。用户可以通过操作5计算必要的燃油摄入量。
我决定将抽象工厂设计模式应用于我的代码。以下是未应用模式的代码的当前版本:
#include <iostream>
#include <stdio.h>
using namespace std;
class FlyingMode {
protected:
float time, fuel_rate, start, end, pace, distance;
float total;
public:
FlyingMode(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0){
time = _time;
fuel_rate = _fuel_rate;
start = _start;
end = _end;
pace = _pace;
distance = _distance;
total = 0;
}
virtual ~FlyingMode() {}
virtual float calcFuel(){
return 0;
}
};
class Holding: public FlyingMode{
public:
Holding(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0)
:FlyingMode(_time, _fuel_rate, _start, _end, _pace, _distance) { }
float calcFuel(){
total = (time * fuel_rate * 60);
return total;
}
};
class Raising: public FlyingMode{
public:
Raising(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0)
:FlyingMode(_time, _fuel_rate, _start, _end, _pace, _distance) { }
float calcFuel (){
if(start < end && pace != 0 ){
float rising_time = (end - start)/pace;
total = rising_time * fuel_rate;
return total;
}else{
return 0;
}
}
};
class Landing: public FlyingMode{
public:
Landing(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0)
:FlyingMode(_time, _fuel_rate, _start, _end, _pace, _distance) { }
float calcFuel (){
if(start > end && pace != 0 ){
float landing_time = (start - end)/pace;
total = landing_time * fuel_rate;
return total;
}else{
return 0;
}
}
};
class Straight: public FlyingMode{
public:
Straight(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0)
:FlyingMode(_time, _fuel_rate, _start, _end, _pace, _distance) { }
float calcFuel (){
if(distance != 0 || pace != 0 ){
float straight_time = distance/pace;
total = straight_time * fuel_rate;
return total;
}else{
return 0;
}
}
};
// Main function for the program
int main( ){
char op = 's';
float time=0, fuel_rate=0, start=0, end=0, pace=0, distance=0;
float total = 0;
while(op != 'x') {
FlyingMode *mode;
Holding hold;
Raising raise;
Landing land;
Straight straight;
float hold_result, raise_result, land_result, str_result;
cout << "Please select an operation: " << endl;
cout << "1 ---> Holding flight" << endl;
cout << "2 ---> Raising" << endl;
cout << "3 ---> Landing " << endl;
cout << "4 ---> Straight " << endl;
cout << "5 ---> Calculate total fuel consumption" << endl;
cout << "x ---> Exit " << endl;
cin >> op;
switch(op){
case '1':
cout << "Holding time (minutes): ";
cin >> time;
cout << "Fuel rate (kg/sec): ";
cin >> fuel_rate;
//call holding fuel
hold = Holding(time, fuel_rate, 0, 0, 0, 0);
mode = &hold;
hold_result = mode -> calcFuel();
total += hold_result;
break;
case '2':
cout << "Enter starting altitude of raising (meters): ";
cin >> start;
cout << "Enter ending altitude of raising (meters):";
cin >> end;
cout << "Enter raising pace (meter/sec): ";
cin >> pace;
cout << "Fuel rate (kg/sec): ";
cin >> fuel_rate;
raise = Raising(0, fuel_rate, start, end, pace, 0);
//call raising fuel
mode = &raise;
raise_result = mode -> calcFuel();
total += raise_result;
break;
case '3':
cout << "Enter starting altitude of landing (meters): ";
cin >> start;
cout << "Enter ending altitude of landing (meters): ";
cin >> end;
cout << "Enter landing pace (meter/sec): ";
cin >> pace;
cout << "Fuel rate (kg/sec): ";
cin >> fuel_rate;
land = Landing(0, fuel_rate, start, end, pace, 0);
//call landing fuel
mode = &land;
land_result = mode
-> calcFuel();
total += land_result;
break;
case '4':
cout << "Enter distance for straight flight (meters): ";
cin >> distance;
cout << "Enter flight pace (meter/sec): ";
cin >> pace;
cout << "Fuel rate (kg/sec): ";
cin >> fuel_rate;
straight = Straight(0, fuel_rate, 0, 0, pace, distance);
//call straight fuel
mode = &straight;
str_result = mode -> calcFuel();
total += str_result;
break;
case '5':
cout <<"Total fuel requirement: "<< total << " kg"<< endl;
total = 0;
break;
case 'x':
return 0;
default:
continue;
}
}
return 0;
}
我对抽象工厂设计的应用感到有些困惑。到目前为止,我已经创建了这些类:
FlightModeInterface.h
class FlightModeInterface{
protected:
float time, fuel_rate, start, end, pace, distance;
float total;
public:
enum FLIGHT_MODES{
HOLDING,
RAISING,
LANDING,
STRAIGHT
};
FlightModeInterface(float, float, float,
float, float, float);
virtual ~FlightModeInterface(){ }
virtual float calcFuel() = 0;
static FlightModeInterface* createFactory(FLIGHT_MODES);
};
Holding.h
class Holding: public FlightModeInterface{
public:
Holding(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0)
:FlightModeInterface(_time, _fuel_rate, _start, _end, _pace, _distance){ };
virtual float calcFuel(){
total = (time * fuel_rate * 60);
return total;
}
};
Landing.h
class Landing: public FlightModeInterface{
public:
Landing(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0)
:FlightModeInterface(_time, _fuel_rate, _start, _end, _pace, _distance){ };
virtual float calcFuel (){
if(start > end && pace != 0 ){
float landing_time = (start - end)/pace;
total = landing_time * fuel_rate;
return total;
}else{
return 0;
}
}
};
Raising.h
class Raising: public FlightModeInterface{
public:
Raising(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0)
:FlightModeInterface(_time, _fuel_rate, _start, _end, _pace, _distance){ };
virtual float calcFuel (){
if(start < end && pace != 0 ){
float rising_time = (end - start)/pace;
total = rising_time * fuel_rate;
return total;
}else{
return 0;
}
}
};
Straight.h
class Straight: public FlightModeInterface{
public:
Straight(float _time=0, float _fuel_rate=0, float _start=0,
float _end=0, float _pace=0, float _distance=0)
:FlightModeInterface(_time, _fuel_rate, _start, _end, _pace, _distance){ };
virtual float calcFuel (){
if(distance != 0 || pace != 0 ){
float straight_time = distance/pace;
total = straight_time * fuel_rate;
return total;
}else{
return 0;
}
}
};
FlightModeFactory.cpp
class FlightModeFactory{
public:
static FlightModeInterface* createFactory(FlightModeInterface::FLIGHT_MODES mode){
if(mode == FlightModeInterface::FLIGHT_MODES::HOLDING){
//HOW TO FILL???
}
else if(mode == FlightModeInterface::FLIGHT_MODES::LANDING){
}
else if(mode == FlightModeInterface::FLIGHT_MODES::RAISING){
}else if(mode == FlightModeInterface::FLIGHT_MODES::STRAIGHT){
}
}
};
正如您所看到的,我对如何填充FlightModeFactory.cpp中的if-else语句感到困惑。关于如何从这一点继续工厂设计模式的任何想法?在Holding.h,Landing.h等中填写calcFuel方法是否正确?
答案 0 :(得分:1)
使用
if(mode == FlightModeInterface::FLIGHT_MODES::HOLDING){
//HOW TO FILL???
}
else if(mode == FlightModeInterface::FLIGHT_MODES::LANDING){
}
else if(mode == FlightModeInterface::FLIGHT_MODES::RAISING){
}
else if(mode == FlightModeInterface::FLIGHT_MODES::STRAIGHT){
}
是一个糟糕的实现。更好的实施方式是:
mode
。FlightModeFactory.h:
class FlightModeFactory
{
public:
typedef FlightModeInterface* (*Builder)();
static void registerBuilder(FlightModeInterface::FLIGHT_MODES mode,
Builder builder);
static FlightModeInterface* build(FlightModeInterface::FLIGHT_MODES mode);
};
FlightModeFactory.cpp:
typedef std::map<FlightModeInterface::FLIGHT_MODES, FlightModeFactory::Builder> BuilderMap;
static BuilderMap& getBuilderMap()
{
static BuilderMap builderMap;
return builderMap;
}
void FlightModeFactory::registerBuilder(FlightModeInterface::FLIGHT_MODES mode,
Builder builder)
{
getBuilderMap()[mode] = builder;
}
FlightModeInterface* FlightModeFactory::build(FlightModeInterface::FLIGHT_MODES mode)
{
Builder builder = getBuilderMap()[mode];
if ( builder )
{
return builder();
}
else
{
// assert()??
return nullptr;
}
}
现在,注册构建器函数。
Holding.cc:
// Function to build a Holding.
static FlightModeInterface* buildHolding()
{
return new Holding;
}
// Register the builder function.
static int registerBuilder()
{
FlightModeInterface::registerBuilder(FlightModeInterface::FLIGHT_MODES::HOLDING,
buildHolder);
return 0;
}
static int dummy = registerBuilder();
为FlightModeInterface的其他子类型注册类似的函数。
答案 1 :(得分:0)
[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile = /tmp/supervisord.pid
[program:rserver]
user=root
command=/usr/lib/rstudio-server/bin/rserver
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
startsecs=0
autorestart=false
exitcodes=0
[program:shinyserver]
user=root
startsecs = 0
command=/bin/bash -c "exec shiny-server >> /var/log/shiny-server.log 2>&1"
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=false
redirect_stderr=true