工廠方法的核心思想就是將具體的實例化推遲到子類。與簡單工廠相比,它彌補了簡單工廠的一些不足,如:簡單工廠打破了開閉原則!工廠方法只負責創建對象,將原本的邏輯判斷放到了client中。下面是用簡單工廠實現的一個例子:
class IProduct
{
public:
virtual void Function() = 0;
};
class Product_A : public IProduct
{
public:
virtual void Function() override
{
}
};
class Product_B : public IProduct
{
public:
virtual void Function() override
{
}
};
class Creator
{
public:
static IProduct factory(int type)
{
if (/* ... */)
return new Product_A();
else if (/* ... */)
return new Product_B();
}
};
int main()
{
IProduct product = Creator.factory(type);
}
若要對Prodect進行拓展,比如添加一個產品Product_C,那麼我們就要去修改Creator,這樣就不符合開閉原則。下面是用工廠方法實現的代碼示例:
class IProduct
{
public:
virtual void Function() = 0;
};
class Product_A : public IProduct
{
public:
virtual void Function() override
{
}
};
class Product_B : public IProduct
{
public:
virtual void Function() override
{
}
};
class ICreator
{
public:
virtual IProduct* create() = 0;
};
class Creator_A : public ICreator
{
public:
virtual IProduct* create() override
{
return new Product_A();
}
};
class Creator_B : public ICreator
{
public:
virtual IProduct* create() override
{
return new Product_B();
}
};
下面是客戶端代碼:
IProduct create(int type)
{
if (/* ... */)
return Creator_A::create();
else if (/* ... */)
return Creator_B::create();
}
int main()
{
IProduct product = create(type);
}
將變化部分交給了客戶端,這樣就符合開閉原則了。現在要想拓展功能,只需要寫相應的類和工廠就行了,邏輯部分只有客戶端會改變。
你可能會說,有必要那麼麻煩,用工廠只封裝一句new 語句。當然這裏只是例子,在現實設計中,工廠中往往不止這一句調用。就算只有這一句也是值得的,它爲以後的修改提供了很大的方便。假如客戶端中要用到上千個產品,那就要有上千個new,現在要對產品的創建過程做一些改動……悲劇了,要改上千個地方。但如果我們用工廠來封裝new,只需要修改兩個具體工廠Create_A和Create_B就行了。