您的位置:首页 > 其它

设计模式之抽象工厂

2015-08-14 17:06 197 查看
最近在学习设计模式,感觉蛮不错的,这里做点笔记(主要是自己的理解)

抽象工厂(abstract factory)也就是对工厂的抽象利用继承的向上性质和虚函数的的覆盖性质完整了接口的统一。

具体UML如下:



比如一个生产汽车部件的工厂就是一种抽象,因为生产汽车部件的工厂可以分为生产小型卡车部件、小轿车部件、大型卡车部件等工厂(假设每中工厂只生产一种车的部件)。这类的抽象都属于AbstractFactory。

我们都知道汽车是由发动机、轮子、车架等组装起来的,这里的发动机、轮子、车架也是一种抽象。因为每种类型的车需要的部件去不同,如轮子的大小、发动的型号、车架的种类等,只是在组装不同的汽车时用到不同的类型的实例罢了。这些抽象都属于Abstractproduct。

假设在生产CarA、CarB、CarC这三种汽车分别需要用到以下Product:

轮子的类型为:ProductWheelA、ProductWheelB、ProductWheelC;

发动机用到的具体种类为:ProductEngineA、ProductEngineB、ProductEngineC;

车架用到的具体种类为:ProductFrameA、ProductFrameB、ProductFrameC;

抽象轮子和特例化轮子代码如下:


class AbstractProductWheel
{
virtual void show()const = 0;
};
class ProductWheelA:public AbstractProductWheel
{
virtual void show()const
{
cout<<"I am a WheelA"<<endl;
}
};
class ProductWheelB:public AbstractProductWheel
{
virtual void show()const
{
cout<<"I am a WheelB"<<endl;
}
};
class ProductWheelC:public AbstractProductWheel
{
virtual void show()const
{
cout<<"I am a WheelC"<<endl;
}
};


抽象发动机和特例化发动机代码如下:

class AbstractProductEngine
{
virtual void show()const = 0;
};
class ProductEngineA:public AbstractProductEngine
{
virtual void show()const
{
cout<<"I am a EngineA"<<endl;
}
};
class ProductEngineB:public AbstractProductEngine
{
virtual void show()const
{
cout<<"I am a EngineB"<<endl;
}
};
class ProductEngineC:public AbstractProductEngine
{
virtual void show()const
{
cout<<"I am a EngineC"<<endl;
}
};


抽象车架和特例化车架代码如下:

class AbstractProductFrame
{
virtual void show()const = 0;
};
class ProductFrameA:public AbstractProductFrame
{
virtual void show()const
{
cout<<"I am a FrameA"<<endl;
}
};
class ProductFrameB:public AbstractProductFrame
{
virtual void show()const
{
cout<<"I am a FrameB"<<endl;
}
};
class ProductFrameC:public AbstractProductFrame
{
virtual void show()const
{
cout<<"I am a FrameC"<<endl;
}
};


汽车工厂造车就需要生产相应的零部件(这些都是自己生产)的抽象类如下:

class AbstractProductCarPart
{
virtual AbstractProductWheel *CreateWheel()const = 0;
virtual AbstractProductEngine *CreateEngine()const = 0;
virtual AbstractProductFrame * CreateFrame()const = 0;
};


这三类类型的车类的实现:

class ProductCarAPart:public AbstractProductCarPart
{
virtual AbstractProductWheel *CreateWheel()const
{
return new ProductWheelA;
}
virtual AbstractProductEngine *CreateEngine()const
{
return new ProductEngineA;
}
virtual AbstractProductFrame *CreateFrame()const
{
return new ProductFrameA;
}
};
class ProductCarBPart:public AbstractProductCarPart
{
virtual AbstractProductWheel *CreateWheel()const
{
return new ProductWheelB;
}
virtual AbstractProductEngine *CreateEngine()const
{
return new ProductEngineB;
}
virtual AbstractProductFrame *CreateFrame()const
{
return new ProductFrameB;
}
};
class ProductCarCPart:public AbstractProductCarPart
{
virtual AbstractProductWheel *CreateWheel()const
{
return new ProductWheelC;
}
virtual AbstractProductEngine *CreateEngine()const
{
return new ProductEngineC;
}
virtual AbstractProductFrame *CreateFrame()const
{
return new ProductFrameC;
}
};


这里我定义一个组装厂,把部件组装成汽车:

class AssemblingCars
{
public:
void CreateCar(AbstractProductCarPart &factory)
{
AbstractProductWheel *Wheel = factory.CreateWheel();
AbstractProductEngine *Engine = factory.CreateEngine();
AbstractProductFrame *Frame = factory.CreateFrame();

Wheel->show();
Engine->show();
Frame->show();

delete Wheel;
delete Engine;
delete Frame;
}
};


测试主函数的内容:

int main()
{
ProductCarAPart CarPartA;
ProductCarBPart CarPartB;
ProductCarCPart CarPartC;

AssemblingCars AsFactory;
cout<<"组装CarA"<<endl;
AsFactory.CreateCar(CarPartA);
cout<<"组装CarB"<<endl;
AsFactory.CreateCar(CarPartB);
cout<<"组装CarB"<<endl;
AsFactory.CreateCar(CarPartC);
system("pause");
}


测试结果:



总结:

好处是:

1、充分利用了多态性不管什么具体产品都返回抽象产品。

2、充分利用了封装性,内部产品发生变化时外部使用者不会受到影响。

缺点是:如果增加了新的产品,就必须得修改工厂(Factory),不满足闭合原则。

适用性:

在以下情况下应当考虑使用抽象工厂模式:

一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

这个系统有多于一个的产品族,而系统只消费其中某一产品族。

同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。

系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: