设计模式(001)创建型之工厂模式

本文介绍了简单工厂模式和工厂方法模式在对象创建中的应用,通过一个简单的计算器示例展示了两种模式的C++和Java实现。简单工厂模式适合对象类型较少且不需频繁扩展的场景,而工厂方法模式具有更好的可扩展性,适用于对象类型多的情况。文章强调了两种模式在设计思想和扩展性上的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工厂模式包括简单工厂模式和工厂方法模式,它们都用于对象的创建,但是它们之间存在一些区别:

①设计思想不同:
        简单工厂模式的设计思想是将对象的创建过程封装起来,从而将客户端和具体的实现类解耦,客户端只需要知道所需对象的类型,而不需要知道对象的具体创建过程。工厂方法模式的设计思想是定义一个用于创建对象的接口,让子类决定实例化哪个类。即工厂方法模式将对象的创建委托给子类来完成,从而使得客户端无需知道所需对象的具体类型。

②类型的区别:
        简单工厂模式只有一个具体的工厂类来创建对象,它通过一个静态方法或一个实例化方法来创建对象,客户端只需要传入参数来指定要创建的对象类型。工厂方法模式则包含一个抽象的工厂类和多个具体的工厂子类,每个工厂子类负责创建一种具体类型的对象。客户端通过调用工厂方法来创建对象,而工厂方法会被具体的工厂子类所实现,从而根据客户端的需求创建相应类型的对象。

③可扩展性不同:
        简单工厂模式的扩展性不太好,因为添加新的对象类型需要修改工厂类的代码。工厂方法模式具有很好的可扩展性,因为只需要添加一个新的具体工厂子类即可创建新的对象类型。

因此,简单工厂模式适用于对象类型比较少,且不太需要扩展的场景,而工厂方法模式适用于对象类型比较多,且需要扩展的场景。简单工厂模式最大的优点在于工厂类中包含了必要的判断逻辑,根据客户端的选择条件动态实例化相关的类,对于客户端来说,祛除了与具体产品的依赖。而工厂方法模式是把简单工厂的内部逻辑判断移到了客户端代码来实现。简单工厂模式想加功能(如计算平方、开方)需要改工厂类,工厂方法模式则是增加工厂类,改客户端。

一、简单工厂模式

1、场景设计

        实现一个简单的计算器,输入操作数A、操作数B、运算符C,得到计算结果result。使用简单工厂模式。

2、C++实现

#include <iostream>
#include <string>

using namespace std;

//运算类
class Operation{
    //成员变量
    private:
         double numA;
         double numB;
    //成员函数声明
    public:
        double getNumA(void);
        void setNumA(double value);

        double getNumB(void);
        void setNumB(double value);

        virtual double GetResult(){
            double result = 0;
            return result;
        }
};
//成员函数定义
double Operation::getNumA(void){
    return numA;
}
void Operation::setNumA(double value){
    numA = value;
}
double Operation::getNumB(void){
    return numB;
}
void Operation::setNumB(double value){
    numB = value;
}
//加法类 继承运算类
class OperationAdd:public Operation{
    public:
        double GetResult(){
            double result = 0;
            result = getNumA() + getNumB();
            return result;
        }
};
//减法类 继承运算类
class OperationSub:public Operation{
    public:
        double GetResult(){
            double result = 0;
            result = getNumA() - getNumB();
            return result;
        }
};
//乘法类 继承运算类
class OperationMul:public Operation{
    public:
        double GetResult(){
            double result = 0;
            result = getNumA() * getNumB();
            return result;
        }
};
//除法类 继承运算类
class OperationDiv:public Operation{
    public:
        double GetResult(){
            double result = 0;
            if(getNumB() == 0){
                throw "Division by zero condition!";
            }
            result = getNumA() / getNumB();
            return result;
        }
};
//简单工厂
class OperationFactory{
    public:
        static Operation* createOperate(string operate);
};

Operation* OperationFactory::createOperate(string operate){
    Operation *oper = NULL;
    if(operate.compare("+")  == 0){
        oper = new OperationAdd();
    }else if(operate.compare("-")  == 0){
        oper = new OperationSub();
    }else if(operate.compare("*")  == 0){
        oper = new OperationMul();
    }else if(operate.compare("/")  == 0){
        oper = new OperationDiv();
    }
    return oper;
}

int main()
{
    while(true){
        double A,B;
        string C;
        cout << "Input Num A:" << endl;
        cin >> A;
        cout << "Select Opera Char(+,-,*,/):" << endl;
        cin >> C;
        cout << "InPut Num B:" << endl;
        cin >> B;
        Operation *oper;
        oper = OperationFactory::createOperate(C);
        if(oper == NULL){
           cout << "Opera Char Error,please repeat" << endl;
           continue;
        }
        oper->setNumA(A);
        oper->setNumB(B);
        try {
          double result = oper->GetResult();
          cout << A << C << B << "=" << result << endl;
        }catch (const char* msg) {
          cerr << msg << endl;
        }
    }
    return 0;
}

3、Java实现

package creatingpattern.simplefactory;

import java.util.Scanner;

public class SimpleFactoryDemo {
    //运算类
    static class Operation{
        double numA;
        double numB;
        public double getNumA() {
            return numA;
        }
        public void setNumA(double numA) {
            this.numA = numA;
        }
        public double getNumB() {
            return numB;
        }
        public void setNumB(double numB) {
            this.numB = numB;
        }
        public double GetResult() throws Exception {
            double result = 0;
            return result;
        }
    };
    //加法类 继承运算类
    static class OperationAdd extends Operation{
        @Override
        public double GetResult(){
            double result = 0;
            result = getNumA() + getNumB();
            return result;
        }
    };
    //减法类 继承运算类
    static class OperationSub extends Operation{
        @Override
        public double GetResult(){
            double result = 0;
            result = getNumA() - getNumB();
            return result;
        }
    };
    //乘法类 继承运算类
    static class OperationMul extends Operation{
        @Override
        public double GetResult(){
            double result = 0;
            result = getNumA() * getNumB();
            return result;
        }
    };
    //除法类 继承运算类
    static class OperationDiv extends Operation{
        @Override
        public double GetResult() throws Exception {
            double result = 0;
            if(getNumB() == 0){
                throw new Exception("Division by zero condition!");
            }
            result = getNumA() / getNumB();
            return result;
        }
    };

    //简单工厂
    static class OperationFactory{
        public static Operation createOperate(String operate){
            Operation oper = null;
            if(operate.equalsIgnoreCase("+")){
                oper = new OperationAdd();
            }else if(operate.equalsIgnoreCase("-")){
                oper = new OperationSub();
            }else if(operate.equalsIgnoreCase("*")){
                oper = new OperationMul();
            }else if(operate.equalsIgnoreCase("/")){
                oper = new OperationDiv();
            }
            return oper;
        }
    };

    public static void main(String args[]) {
        while(true){
            double A,B;
            String C;
            System.out.println("Input Num A:");
            Scanner scanner = new Scanner(System.in);
            A = scanner.nextDouble();
            System.out.println("Select Opera Char(+,-,*,/):");
            C = scanner.next();
            System.out.println("InPut Num B:");
            B = scanner.nextDouble();
            Operation oper = OperationFactory.createOperate(C);
            if(oper == null){
                System.out.println("Opera Char Error,please repeat");
                continue;
            }
            oper.setNumA(A);
            oper.setNumB(B);
            try {
                double result = oper.GetResult();
                System.out.println("" +  A +  C + B + "=" + result);
            }catch (Exception e) {
                System.out.println("ERROR: " + e);
            }
        }
    }
}

二、工厂方法模式

1、场景设计

        实现一个简单的计算器,输入操作数A、操作数B、运算符C,得到计算结果result。使用工厂方法模式。

2、C++实现

#include <iostream>
#include <string>

using namespace std;

//运算类
class Operation{
    //成员变量
    private:
         double numA;
         double numB;
    //成员函数声明
    public:
        double getNumA(void);
        void setNumA(double value);

        double getNumB(void);
        void setNumB(double value);

        virtual double GetResult(){
            double result = 0;
            return result;
        }
};
//成员函数定义
double Operation::getNumA(void){
    return numA;
}
void Operation::setNumA(double value){
    numA = value;
}
double Operation::getNumB(void){
    return numB;
}
void Operation::setNumB(double value){
    numB = value;
}
//加法类 继承运算类
class OperationAdd:public Operation{
    public:
        double GetResult(){
            double result = 0;
            result = getNumA() + getNumB();
            return result;
        }
};
//减法类 继承运算类
class OperationSub:public Operation{
    public:
        double GetResult(){
            double result = 0;
            result = getNumA() - getNumB();
            return result;
        }
};
//乘法类 继承运算类
class OperationMul:public Operation{
    public:
        double GetResult(){
            double result = 0;
            result = getNumA() * getNumB();
            return result;
        }
};
//除法类 继承运算类
class OperationDiv:public Operation{
    public:
        double GetResult(){
            double result = 0;
            if(getNumB() == 0){
                throw "Division by zero condition!";
            }
            result = getNumA() / getNumB();
            return result;
        }
};

//纯虚函数(工厂接口)
class IFactory{
    public:
        virtual Operation* CreateOperation()=0;
};

//加法工厂
class AddFactory:public IFactory {
    Operation* CreateOperation() {
        return new OperationAdd();
    }
};
//减法工厂
class SubFactory:public IFactory {
    Operation* CreateOperation() {
        return new OperationSub();
    }
};
//乘法工厂
class MulFactory:public IFactory {
    Operation* CreateOperation() {
        return new OperationMul();
    }
};
//除法工厂
class DivFactory:public IFactory {
    Operation* CreateOperation() {
        return new OperationDiv();
    }
};

int main()
{
    while(true){
        double A,B;
        string C;
        cout << "Input Num A:" << endl;
        cin >> A;
        cout << "Select Opera Char(+,-,*,/):" << endl;
        cin >> C;
        cout << "InPut Num B:" << endl;
        cin >> B;
        IFactory *operFactory = NULL;
        if(C.compare("+")  == 0){
            operFactory = new AddFactory();
        }else if(C.compare("-")  == 0){
            operFactory = new SubFactory();
        }else if(C.compare("*")  == 0){
            operFactory = new MulFactory();
        }else if(C.compare("/")  == 0){
            operFactory = new DivFactory();
        }else {
            cout << "Opera Char Error,please repeat" << endl;
            continue;
        }
        Operation *oper = operFactory->CreateOperation();
        oper->setNumA(A);
        oper->setNumB(B);
        try {
          double result = oper->GetResult();
          cout << A << C << B << "=" << result << endl;
        }catch (const char* msg) {
          cerr << msg << endl;
        }
    }
    return 0;
}

3、Java实现

package creatingpattern.factorymethod;

import java.util.Scanner;

public class FactoryMethodDemo {
    //运算类
    static class Operation{
        double numA;
        double numB;
        public double getNumA() {
            return numA;
        }
        public void setNumA(double numA) {
            this.numA = numA;
        }
        public double getNumB() {
            return numB;
        }
        public void setNumB(double numB) {
            this.numB = numB;
        }
        public double GetResult() throws Exception {
            double result = 0;
            return result;
        }
    };

    //加法类 继承运算类
    static class OperationAdd extends Operation{
        @Override
        public double GetResult(){
            double result = 0;
            result = getNumA() + getNumB();
            return result;
        }
    };
    //减法类 继承运算类
    static class OperationSub extends Operation{
        @Override
        public double GetResult(){
            double result = 0;
            result = getNumA() - getNumB();
            return result;
        }
    };
    //乘法类 继承运算类
    static class OperationMul extends Operation{
        @Override
        public double GetResult(){
            double result = 0;
            result = getNumA() * getNumB();
            return result;
        }
    };
    //除法类 继承运算类
    static class OperationDiv extends Operation{
        @Override
        public double GetResult() throws Exception {
            double result = 0;
            if(getNumB() == 0){
                throw new Exception("Division by zero condition!");
            }
            result = getNumA() / getNumB();
            return result;
        }
    };
    //工厂接口
    interface IFactory{
        Operation CreateOperation();
    }
    //加法工厂
    static class AddFactory implements IFactory {
        @Override
        public Operation CreateOperation() {
            return new OperationAdd();
        }
    }
    //减法工厂
    static class SubFactory implements IFactory {
        @Override
        public Operation CreateOperation() {
            return new OperationSub();
        }
    }
    //乘法工厂
    static class MulFactory implements IFactory {
        @Override
        public Operation CreateOperation() {
            return new OperationMul();
        }
    }
    //除法工厂
    static class DivFactory implements IFactory {
        @Override
        public Operation CreateOperation() {
            return new OperationDiv();
        }
    }

    public static void main(String args[]) {
        while(true){
            double A,B;
            String C;
            System.out.println("Input Num A:");
            Scanner scanner = new Scanner(System.in);
            A = scanner.nextDouble();
            System.out.println("Select Opera Char(+,-,*,/):");
            C = scanner.next();
            System.out.println("InPut Num B:");
            B = scanner.nextDouble();
            IFactory operFactory = null;
            if(C.equalsIgnoreCase("+")){
                operFactory = new AddFactory();
            }else if(C.equalsIgnoreCase("-")){
                operFactory = new SubFactory();
            }else if(C.equalsIgnoreCase("*")){
                operFactory = new MulFactory();
            }else if(C.equalsIgnoreCase("/")){
                operFactory = new DivFactory();
            }else{
                System.out.println("Opera Char Error,please repeat");
                continue;
            }
            Operation oper = operFactory.CreateOperation();
            oper.setNumA(A);
            oper.setNumB(B);
            try {
                double result = oper.GetResult();
                System.out.println("" +  A +  C + B + "=" + result);
            }catch (Exception e) {
                System.out.println("ERROR: " + e);
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值