出租车计费程序——多态实现

出租车计价计算服务:

起步价6元(两公里以内),超出(含)两公里至八公里以内的公里数每公里按1.5元计费。超出(含)八公里以外的公里数(每公里加收50%空驶费)。中间如果有等待,等待时间计费为每分钟0.25元。最终的收费以元取整(四舍五入)。

非功能限制:要求复杂度尽量低,看看能否不用if else、switch、?:等判断语句实现功能

一、TaxiTest.cpp

#include <iostream>
#include "TaxiFee.hpp"
#include <assert.h>
#include <math.h>
#include <vector>
#define EPSLION  1e-8
using namespace std;
extern bool isEqual(double a, double b);

int main() {
	TaxiFee* taxiFee;
	TaxiFeeFactory* taxiFeeFactory = new TaxiFeeFactory();
	vector<vector<double>> testCase = {
			{1.0, 0.0, 6.0},
			{1.0, 2.0, 7.0},
			{6.0, 0.0, 12.0},
			{10.0, 3.0, 20.0},
			{1.0, 1.0, 6.0},
			{2.0, 0.0, 6.0},
			{8.0, 0.0, 15.0}
	};
	for(size_t i = 0; i < testCase.size(); i++){
		taxiFee = taxiFeeFactory->getTaxiFeeInst(testCase[i][0]);
		cout<<i<<":";
		if(!taxiFee){
			cout<<"Undefined behavior about this distance!"<<endl;
			continue;
		}
		assert(isEqual(taxiFee->getTotalFee(testCase[i][0], testCase[i][1]), testCase[i][2]));
		cout<<"Success!"<<endl;
	}
	delete taxiFee;
	delete taxiFeeFactory;
	return 0;
}


二、TaxiFee.hpp

#include <unordered_map>
class TaxiFee{
public:
	const double waitFeePerMinute = 0.25;
	const double startPrice = 6.0;
	const double startDistance = 2.0;
	const double adjustDistance = 8.0;
	const double perKilometerPrice = 1.5;
	const double adjustRatio = 0.5;
	TaxiFee(){};
	virtual double computeDistanceFee(double distance) = 0;
	virtual ~TaxiFee(){};
	double computeWaitTimeFee(double distance);
	double getTotalFee(double time, double distance);
};

class StartPriceFee: public TaxiFee{
public:
	StartPriceFee(){};
	double computeDistanceFee(double distance);
	~StartPriceFee(){};
};

class NoramlPriceFee: public TaxiFee{
public:
	NoramlPriceFee(){};
	double computeDistanceFee(double distance);
	~NoramlPriceFee(){};
};

class AdjustedPrcieFee: public TaxiFee{
public:
	AdjustedPrcieFee(){};
	double computeDistanceFee(double distance);
	~AdjustedPrcieFee(){};
};


class TaxiFeeFactory{
private:
	std::unordered_map<int, TaxiFee*> feeFuncMap;
	const int MAX_DISTANCE = 10000;
	TaxiFee* startPriceFee;
	TaxiFee* noramlPriceFee;
	TaxiFee* adjustedPrcieFee;

public:
	TaxiFeeFactory(){
		startPriceFee = new StartPriceFee();
		noramlPriceFee = new NoramlPriceFee();
		adjustedPrcieFee = new AdjustedPrcieFee();
		feeFuncMap = {
				{0, startPriceFee},
				{1, noramlPriceFee},
				{-1, nullptr}
		};
		for(int i = 2; i <= MAX_DISTANCE; i++){
			this->feeFuncMap[i] = adjustedPrcieFee;
		}
	}
	TaxiFee* getTaxiFeeInst(double distance);
	~TaxiFeeFactory(){
		delete startPriceFee;
		delete noramlPriceFee;
		delete adjustedPrcieFee;
		delete this;
	}
};

三、TaxiFee.cpp

#include "TaxiFee.hpp"
#include <math.h>
#include <iostream>
using namespace std;
#define EPSLION  1e-8

bool isGreater(double a, double b){
	return a > b +EPSLION;
}

bool isEqual(double a, double b){
	return abs(a - b) < EPSLION;
}

double TaxiFee::computeWaitTimeFee(double minute){
	return  minute * waitFeePerMinute;
}

double StartPriceFee::computeDistanceFee(double distance){
	return startPrice;
}

double NoramlPriceFee::computeDistanceFee(double distance){
	return startPrice + (distance - startDistance) * perKilometerPrice;
}

double AdjustedPrcieFee::computeDistanceFee(double distance){
	return startPrice + (adjustDistance - startDistance) * perKilometerPrice + (distance - adjustDistance)*(1 + adjustRatio)*perKilometerPrice;
}

double TaxiFee::getTotalFee(double distance, double time){
	double totalFee = this->computeDistanceFee(distance) + this->computeWaitTimeFee(time);
	return round(totalFee);
}

int getKey(double distance){
	int key = (int)(distance)/2;
	key = ceil(key/4.0);
	return key;
}

TaxiFee* TaxiFeeFactory::getTaxiFeeInst(double distance){
	int key = isGreater(distance, 0.0)? getKey(distance): -1;
	return feeFuncMap[key];
}

posted on 2022-01-19 23:38  七昂的技术之旅  阅读(682)  评论(0)    收藏  举报

导航