У меня есть программа, в которой пользователь вводит операции плоскости. Пользователь может выбрать как можно больше операций (удерживание, прямое, посадочное и т. Д.). Пользователь может рассчитать необходимый расход топлива с операцией 5.Применение абстрактного шаблона фабричного проектирования в C++
Я решил применить шаблон шаблона для заводских образцов к моему коду. Вот текущий вариант кода без рисунка применяется:
#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;
}
Я немного запутался для применения Abstract Factory Design. До сих пор я создал эти классы:
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){
}
}
};
Как вы можете видеть, я запутался с тем, как заполнить инструкции if-else в FlightModeFactory.cpp. Любые идеи о том, как продолжить Factory Design Pattern с этого момента? Правильно ли заполнять методы calcFuel в Holding.h, Landing.h и т. Д.?
'// КАК ЗАПОЛНИТЬ' нечто вроде 'return new Holding (...);'. Но я на самом деле рекомендую ввести возвращаемый 'std :: unique_ptr 'вместо исходного указателя. –
Вам нужно заменить '// HOW TO FILL ???' на 'return new Holding (...);', но вам также необходимо передать все переменные-конструкторы в ваш заводский метод. Однако это не похоже на дизайн «Абстрактной фабрики» для меня. Я подумал, что именно там вы создали конкретную фабрику для каждого типа объектов, которые хотите моделировать, скажем, если бы у вас были разные типы самолетов, у каждого из которых был набор поведенческих «компонентов». – Galik
Также я бы рассмотрел возможность вывести все переменные из конструктора и передать их функции 'calcFuel();'. Тогда ваш класс интерфейса может быть действительно чистым интерфейсом класса *, и вам не нужно передавать все эти переменные на заводский метод. В принципе, завод предоставляет расчетный объект для каждого типа маневра. – Galik