创建型模式之工厂方法FACTORY METHOD

这里写图片描述
意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method使一个类的实例化延迟到其子类。

我将工厂模式分为三个部分:原料、工厂、购买者

一、原料

这里写图片描述
一般情况下我们的原料属于同种。比如说面积:有圆面积,矩形面积,正方形面积等。这些都属于面积的算法。但是他们具体到某个详细算法时又有所不同,所以我们可以用多个子类继承同一个基类。由于基类不属于某个具体形状。所以它应该定义成抽象类(不能定义对象,只能定义指针和引用,且不能用于函数参数类型和返回值)。纯虚函数只是用来说明,没有具体实现。它的实现应该又每个有具体意义的子类来实现。

基类Shape
#ifndef SHAPE_H
#define SHAPE_H


class Shape
{
    public:
        Shape();
        ~Shape();
        virtual void getArea()=0;

    protected:

    private:
};

#endif // SHAPE_H


#include "Shape.h"

Shape::Shape()
{
    //ctor
}

Shape::~Shape()
{
    //dtor
}
Square子类
#ifndef SQUARE_H
#define SQUARE_H


class Square : public Shape
{
    public:
        Square();

        ~Square();
        void getArea();

    protected:

    private:
};

#endif // SQUARE_H


#include <iostream>

#include "Shape.h"
#include "Square.h"

using namespace std;

Square::Square()
{
    //ctor
}

Square::~Square()
{
    //dtor
}


void Square::getArea(){
    cout<<"这是Square类的方法"<<endl;
}
Circle子类
#ifndef CIRCLE_H
#define CIRCLE_H

class Circle : public Shape
{
    public:
        Circle();
        ~Circle();
        void getArea();

    protected:

    private:
};

#endif // CIRCLE_H


#include <iostream>

#include "Shape.h"
#include "Circle.h"

using namespace std;

Circle::Circle()
{
    //ctor
}

Circle::~Circle()
{
    //dtor
}


void Circle::getArea(){
    cout<<"这是Circle类方法"<<endl;
}

二、工厂

工厂负责加工这些原料,当购买者需要计算某个面积时,工厂就对原料进行加工产生对应某个面积算法的对象。这个地方用抽象类的好处出来了。由于我们原料的子类都是继承与虚基类。所以我们可以直接返回抽象类的指针,利用C++的多态性(当基类指针进入某个子类的对象,就调用对应子类的函数),将原料子类赋给基类指针。这样我们就可以使用基类类型就可以了,而不需要为了完成赋值类型对应,在购买者函数里定义子类类型。也就是说工厂将原料和购买者分离开来。添加、修改原料不会影响购买者,购买者只需要告诉工厂需要购买何种子类就行,而不需要关注具体子类的实现。

factory类
#ifndef SHAPEFACTORY_H
#define SHAPEFACTORY_H

#include <string>
using namespace std;

class ShapeFactory
{
    public:
        ShapeFactory();
        ~ShapeFactory();
        Shape* getShape(string);

    protected:

    private:
};

#endif // SHAPEFACTORY_H

#include <string>
#include "Shape.h"
#include "Square.h"
#include "Circle.h"


#include "ShapeFactory.h"

using namespace std;

ShapeFactory::ShapeFactory()
{
    //ctor
}

ShapeFactory::~ShapeFactory()
{
    //dtor
}


Shape* ShapeFactory::getShape(string type){
    if(type == "CIRCLE"){
        return new Circle();
    }else if(type == "SQUARE"){
        return new Square();
    }
    return NULL;
}

三、购买者

购买者只需要告诉工厂需要何种类就行,不用关注子类实现。如果我们使用字符串完成子类类型对应,实现逻辑上的对应。那么即使原料类名的更改也不会影响到购买者的调用,只需要对负责产出子类的工厂进行修改。而这种修改很容易就可以实现,因为所有的子类都归工厂管理,集中于工厂类中。不需要到购买者中逐一查找在何处有子类对象。

#include "Shape.h"
#include "ShapeFactory.h"

int main(){

    ShapeFactory *factory = new ShapeFactory();
    Shape* circle = factory->getShape("CIRCLE");
    circle->getArea();
    Shape* square = factory->getShape("SQUARE");
    square->getArea();

    return 0;
}

四、java代码

java代码使用interface和implements实现。

package factory;

public class Circle implements Shape {
    public void getArea(){
        System.out.println("这是获取circle面积的方法");
    }
}
package factory;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ShapeFactory factory = new ShapeFactory();
        Shape circle = factory.getShape("CIRCLE");
        circle.getArea();
        Shape square = factory.getShape("SQUARE");
        square.getArea();

    }

}
package factory;

public interface Shape {
    void getArea();
}
package factory;

public class ShapeFactory {
    public Shape getShape(String shapeType){
        if(shapeType == null)
            return null;
        if(shapeType.equalsIgnoreCase("CIRCLE")){
            return new Circle();
        }else if(shapeType.equalsIgnoreCase("Square")){
            return new Square();
        }
        return null;

    }
}
package factory;

public class Square implements Shape {
    public void getArea(){
        System.out.println("这是获取square面积的方法");
    }
}

代码链接:c++ CodeBlocks;java eclipse

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值