首页 > 代码库 > 关于工厂模式的一些反思

关于工厂模式的一些反思

之前看了一些关于工厂模式和抽象工厂模式的资料,了解了工厂模式和抽象工厂模式的特点和区别。今天再回来看自己之前写的笔记,又开始迷惑了,下面把自己的一些迷惑和想法记录下来。

1.什么地方会用到简单工厂模式?
在很多开源库中都会出现跨平台的问题。假设有一个窗口模块(即为一个dll),该模块提供窗口的基本功能比如设置标题、设置窗口背景颜色等。在不同的平台里,创建窗口需要调用不同的API,比如windows平台,创建窗口可以调用MFC或者windows的API,在linux平台创建窗口则需要调用X11的API,因此不同平台需要不同的窗口类来实现。设有基类window,子类win_window, linux_window, android_window,代码如下:

在window.h中只定义了抽象类window的接口(这里用来作为例子说明简单工厂模式的使用环境,因此只简单定义了三个接口,且不做功能的实现)和create_window函数。
//window.h



class window
{
  public:
     virtual ~window(){};//必须是虚函数

  public:
     virtual void set_titile(const char* title_) = 0;//纯虚函数
     virtual void set_background_color(int r_, int g_, int b_, int a_) = 0;
     virtual void set_size(int width_, int height_) = 0;
};
window* create_window();

在window.cpp中定义并实现具体子类win_window、linux_window、android_window及函数create_window。代码如下:
//window.cpp


class linux_window
:public window
{
  public:
      ~win_window(){}
  public:
      void set_title(const char* title_){\\暂时不实现功能}
      void set_background_color(int r_, int g_, int b_, int a_){\\暂时不实现功能}
      void set_size(int width_, int height_){\\暂时不实现功能}
};
class android_window
:public window
{
  public:
      ~win_window(){}
  public:
      void set_title(const char* title_){\\暂时不实现功能}
      void set_background_color(int r_, int g_, int b_, int a_){\\暂时不实现功能}
      void set_size(int width_, int height_){\\暂时不实现功能}
};
window* create_window()
{
    window* wind = NULL;

    if(system_str == "win32")
         wind = new win_window();
    else if(system_str == "linux")
         wind = new linux_window();
    else if(system_str == "android")
         wind = new android_window();
    else
         wind = NULL;

    return wind;
}

上面的函数create_window根据不同的系统生成不同的window类,使得外部调用时,不需要考虑跨平台的问题,在任何平台上,外部调用创建窗口的代码都只有一份。
请注意一点,我们在看设计模式书的时候,简单工厂模式一般都是一个类,而我写了一个函数说使用了简单工厂模式,这是不是错误的呢?这里没有错误,设计模型给我们提供的是一种思路,在学习设计模式的时候,我们要掌握重点,学会变通,不要太注重条条框框。

到这里也许还有人会问:如果不定义create_window函数,将create_window函数的代码放到外部创建窗口的地方,不也是可以的吗?

没错,这样也是可以的。但是使用这种方式和使用create_window函数封装创建窗口类的过程比起来,使用create_window有两个优点:
(1)外部调用时,只需调用create_window函数,代码简洁,逻辑清晰;
(2)如果你够细心的话会发现,我在window.h头文件中只定义了window抽象类和create_window函数,并没有声明其他三个子类,而是在window.cpp文件中对三个子类进行声明和实现的。这样做使得三个子类对于外部来说是透明的,外部根本不知道有这三个子类的存在。

这里你也许会问,三个子类对外部透明,有什么好处?
假设这样一种情况:
如果我换了一个窗口模块,这个窗口模块也定义了window抽象类和create_window,但是子类的名称和上一个窗口模块都不一样了,这时候就能看出抽象类对外部透明的好处了。因为之前外部调用都是使用的create_window函数,所以虽然窗口模块改变了,但是只要window抽象类和create_window没有改变,外部不需要改变任何代码就可以使用新的窗口模块。

2.什么地方会用到工厂模式和抽象工厂模式?

3.为什么要用工厂模式和抽象工厂模式?

问题2和3其实可以在问题1里面找到答案。使用工厂模式和抽象工厂模式都是为了隔离对象的创建过程,使得具体类对外部调用透明,即外部不知道有子类的存在。这样在对子类做修改后,外部可以不做修改或者只做极少的修改就可以了。


以上内容纯属自己的一些理解,如果哪里错了,欢迎大家指正。



关于工厂模式的一些反思