Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclassess.
定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類。工廠方法使一個(gè)類的實(shí)例化延遲到其子類。
何時(shí)使用
- 用戶需要一個(gè)類的子類的實(shí)例,但不希望與該類的子類形成耦合
- 用戶需要一個(gè)類的子類的實(shí)例,但用戶不知道該類有哪些子類可用
優(yōu)點(diǎn)
- 使用工廠方法可以讓用戶的代碼和某個(gè)特定類的子類的代碼解耦
- 工廠方法使用戶不必知道它所使用的對(duì)象是怎樣被創(chuàng)建的,只需知道該對(duì)象有哪些方法即可。
簡(jiǎn)單工廠模式
介紹工廠方法模式前,先介紹一下簡(jiǎn)單工廠模式,簡(jiǎn)單工廠模式也是一種工廠方法模式。
簡(jiǎn)單工廠模式又稱靜態(tài)工廠方法模式。從命名上就可以看出這個(gè)模式一定很簡(jiǎn)單。它存在的目的很簡(jiǎn)單:定義一個(gè)用于創(chuàng)建對(duì)象的接口。
如果一個(gè)一些對(duì)象(產(chǎn)品),已經(jīng)確定了并不易改變和添加新的產(chǎn)品,那么久可以使用簡(jiǎn)單工廠模式。下面就是簡(jiǎn)單工廠的例子:
//演示簡(jiǎn)單工廠
public class SimpleFactory {
public static void main(String args[]) throws Exception{
Factory factory = new Factory();
factory.produce("PRO5").run();
factory.produce("PRO6").run();
}
}
//抽象產(chǎn)品
interface MeizuPhone{
void run();
}
//具體產(chǎn)品X2
class PRO5 implements MeizuPhone{
@Override
public void run() {
System.out.println("我是一臺(tái)PRO5");
}
}
class PRO6 implements MeizuPhone{
@Override
public void run() {
System.out.println("我是一臺(tái)PRO6");
}
}
//工廠
class Factory{
MeizuPhone produce(String product) throws Exception{
if(product.equals("PRO5"))
return new PRO5();
else if(product.equals("PRO6"))
return new PRO6();
throw new Exception("No Such Class");
}
}
很容易看出,簡(jiǎn)單工廠模式是不易維護(hù)的,如果需要添加新的產(chǎn)品,則整個(gè)系統(tǒng)都需要修改。如果我們需要添加諸如PRO7、PRO8等產(chǎn)品,直接在工程類中添加即可。但是如果這時(shí)候根部不知道還有什么產(chǎn)品,只有到子類實(shí)現(xiàn)時(shí)才知道,這時(shí)候就需要工廠方法模式。
而在實(shí)際應(yīng)用中,很可能產(chǎn)品是一個(gè)多層次的樹(shù)狀結(jié)構(gòu)。由于簡(jiǎn)單工廠模式中只有一個(gè)工廠類來(lái)對(duì)應(yīng)這些產(chǎn)品,所以實(shí)現(xiàn)起來(lái)是比較麻煩的,那么工廠方法模式正式解決這個(gè)問(wèn)題的,下面就介紹工廠方法模式。
工廠方法模式
工廠方法模式去掉了簡(jiǎn)單工廠模式中工廠方法的靜態(tài)屬性,使得它可以被子類繼承。這樣在簡(jiǎn)單工廠模式里集中在工廠方法上的壓力可以由工廠方法模式里不同的工廠子類來(lái)分擔(dān)。
針對(duì)上面的例子,如果使用工廠方法模式,即將工廠定義為一個(gè)接口,然后由具體的工廠來(lái)確定需要生成什么樣的產(chǎn)品,為了與簡(jiǎn)單工廠比較,這里還是貼上代碼:
//工廠方法模式
public class FactoryMethod {
public static void main(String args[]){
IFactory bigfactory;
bigfactory = new SmallFactory();
bigfactory.produce().run();
bigfactory = new BigFactory();
bigfactory.produce().run();
}
}
//抽象產(chǎn)品
interface MeizuPhone{
void run();
}
//具體產(chǎn)品*2
class PRO5 implements MeizuPhone{
@Override
public void run() {
System.out.println("我是一臺(tái)PRO5");
}
}
class MX5 implements MeizuPhone{
@Override
public void run() {
System.out.println("我是一臺(tái)MX5");
}
}
interface IFactory{//抽象的工廠
MeizuPhone produce();
}
//工廠*2
class BigFactory implements IFactory{
@Override
public MeizuPhone produce() {
return new PRO5();
}
}
class SmallFactory implements IFactory{
@Override
public MeizuPhone produce() {
return new MX5();
}
}