前言
工厂模式(Factory Pattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
介绍
- 意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行
- 主要解决:主要解决接口选择的问题
- 何时使用:我们明确地计划不同条件下创建不同实例时
- 如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品
- 关键代码:创建过程在其子类执行
案例
简单的计算器程序,由用户输入操作符来实例化运算符对象。并引入异常处理机制。
#pragma once
#include <iostream>
#include <string>
#include <exception>
class Operation {
private:
double numberA{0}, numberB{0};
public:
void setNumberA(double numA_);
void setNumberB(double numB_);
double getNumberA();
double getNumberB();
virtual double getResult();
class OperationException: public std::exception {
public:
const char* what() const throw();
};
class BadOperationException: public Operation::OperationException {
public:
const char* what() const throw();
};
class DivZeroException: public Operation::OperationException {
public:
const char* what() const throw();
};
};
class AddOperation: public Operation {
public:
double getResult();
};
class SubOperation: public Operation {
public:
double getResult();
};
class MulOperation: public Operation {
public:
double getResult();
};
class DivOperation: public Operation {
public:
double getResult();
};
class OperationFactory {
public:
static Operation* createOperation(char operate_);
};
#include "Operation.h"
void Operation::setNumberA(double numA_) {
numberA = numA_;
}
void Operation::setNumberB(double numB_) {
numberB = numB_;
}
double Operation::getNumberA() {
return numberA;
}
double Operation::getNumberB() {
return numberB;
}
double Operation::getResult() {
return 0.0;
}
double AddOperation::getResult() {
double result{0};
result = getNumberA() + getNumberB();
return result;
}
double SubOperation::getResult() {
double result{0};
result = getNumberA() - getNumberB();
return result;
}
double MulOperation::getResult() {
double result{0};
result = getNumberA() * getNumberB();
return result;
}
double DivOperation::getResult() {
double result{0};
try {
if (getNumberB() == 0)
throw Operation::DivZeroException();
}
catch (Operation::DivZeroException& exce_) {
std::cout << exce_.what() << std::endl;
exit(0);
}
result = getNumberA() / getNumberB();
return result;
}
Operation* OperationFactory::createOperation(char operate_) {
try {
Operation* operation = nullptr;
switch (operate_) {
case '+':
operation = new AddOperation;
break;
case '-':
operation = new SubOperation;
break;
case '*':
operation = new MulOperation;
break;
case '/':
operation = new DivOperation;
default:
break;
}
if (operation != nullptr)
return operation;
throw Operation::BadOperationException();
}
catch (Operation::BadOperationException& exce_) {
std::cout << exce_.what() << std::endl;
exit(0);
}
}
const char* Operation::OperationException::what() const throw() {
return "Exception.";
}
const char* Operation::BadOperationException::what() const throw() {
return "Exception: Bad operation.";
}
const char* Operation::DivZeroException::what() const throw() {
return "Exception: Divide 0.";
}