工廠模式
簡單工廠模式
定義一個用於創建對象的接口,讓子類決定實例化哪個類(也可以叫做靜態工廠模式)
1. 角色說明
- 產品:需要創建的複雜對象(一般爲interface/abstract形式)。
- 具體產品:產品的具體實現。
- 工廠類:根據入參返回產品的具體實現。
2. 實例演示
產品
public abstract class Product{
public abstract void a();
public abstract void b();
}
產品實現類
/**
* 具體產品A
*/
public class ProductA extends Product{
@Override
public void a(){
System.out.println("PA a");
}
@Override
public void b(){
System.out.println("PA b");
}
}
/**
* 具體產品B
*/
public class ProductB extends Product{
@Override
public void a(){
System.out.println("PB a");
}
@Override
public void b(){
System.out.println("PB b");
}
}
工廠類
public class Factroy{
public static Product create(String type){
Product p = null;
switch(type){
case "A":
p = new ProductA();break;
case "B":
p = new ProductB();break;
default :
}
return p;
}
}
3.使用
我們這裏使用工廠類的create方法,根據傳入的參數的不同,生成不同的產品。
public void do(){
Factory.create("A").a();
Factory.create("B").b();
}
Output
PA a
PB b
4.總結
- 我們生成複雜對象時,當我們確定只使用一個工廠類的時候,我們可以使用簡單工廠模式。
- 簡單工廠模式可以把創建實例的過程與使用實例分開,降低代碼的耦合度,尤其時當實現類需要大量設置參數的時候(也就是我們new一個對象之後要set很多參數的實例),使用這個實例時我們就不用關心這個對象是如何創建的了
- 像第一條所說,我們只能有一個工廠類,而且我們使用的靜態創建方法,不能被繼承和重寫,這就導致我們如果要添加新的產品必須修改工廠類邏輯,是得工廠類過於複雜,一旦工廠類出錯,則會影響整個系統,這違背了開閉原則。(這也就是簡單工廠的弊端)
工廠方法模式
定義一個接口用來創建對象,讓他的子類去決定實例化哪個類。
1.角色說明
- 抽象產品:定義對象的公共接口用來創建複雜對象
- 具體產品:實現接口
- 抽象工廠:包含一個方法用來返回抽象產品的對象
- 具體工廠:返回具體產品。
2.實例演示
定義抽象產品
public abstract class Product{
public abstract void deal();
}
具體產品實現
public class ProductA extends Product {
@Override
public void deal() {
System.out.println("product A");
}
}
public class ProductB extends Product {
@Override
public void deal() {
System.out.println("product B");
}
}
抽象工廠
public abstract class Factory {
public abstract Product create();
}
具體工廠實現
public class FactoryA extends Factory {
@Override
public Product create() {
return new ProductA();//創建ProductA
}
}
public class FactoryB extends Factory {
@Override
public Product create() {
return new ProductB();//創建ProductB
}
}
3.使用
public void test() {
Factory factoryA = new FactoryA();
Product productA = factoryA.create();
productA.deal();
Factory factoryB = new FactoryB();
Product productB = factoryB.create();
productB.deal();
}
Output
product A
product B
4.總結
- 工廠方法模式符合開閉原則,符合單一職責原則,每個工廠都只負責對應的產品
- 由於一個工廠只能創建一個產品沒所以當新增產品時,就需要新增相應的工廠類,導致系統負責度和性能開銷,引入抽象類也會導致類結構的複雜化
抽象工廠模式
提供一個接口去創建一組相關或者相互依賴的對象,不用去制定他們的具體類。
1.角色說明
- 抽象產品:提供一個公共接口
- 具體產品:一個具體的產品,實現抽象產品接口。
- 抽象工廠:提供一個抽象類去定義一些創建產品的方法。
- 具體工廠:實現抽象工廠中定義的創建產品的方法,每一個具體工廠對應生產一種具體產品。
2.實例演示
抽象公共接口
public abstract class Guitar{
public abstract void getGuitar();
}
public abstract class Bass{
public abstract void getBass();
}
public abstract class Drum{
public abstract void getDrum();
}
具體產品實現
public class ESP extends Guitar{
@Override
public void getGuitar() {
System.out.println("Guitar:ESP");
}
}
public class Fender extends Guitar{
@Override
public void getGuitar() {
System.out.println("Guitar:Fender");
}
}
public class ESP extends Bass{
@Override
public void getBass() {
System.out.println("Bass:ESP");
}
}
public class Fender extends Bass{
@Override
public void getBass() {
System.out.println("Bass:Fender");
}
}
public class Roland extends Drum{
@Override
public void getDrum() {
System.out.println("Drum:Roland");
}
}
public class Gretsch extends Drum{
@Override
public void getDrum() {
System.out.println("Drum:Gretsch");
}
}
抽象工廠
public abstract class BankFactory{
public abstract Guitar createGuitar();
public abstract Bass createBass();
public abstract Drum createDrum();
}
具體工廠類
public class PopBankFactory extends BankFactory{
@Override
public Guitar createGuitar() {
return new Fender();
}
@Override
public Bass createBass(){
return new Fender();
};
@Override
public Drum createDrum(){
return new Gretsch();
};
}
public class RockBankFactory extends BankFactory{
@Override
public Guitar createGuitar() {
return new ESP();
}
@Override
public Bass createBass(){
return new ESP();
};
@Override
public Drum createDrum(){
return new Roland();
};
}
3.使用
這裏我們就可以根據不同的需要生產特定的組合產品了。
public void test(){
System.out.println("--------------------組建一支搖滾樂隊-----------------------");
RockBankFactory rockBand = new RockBankFactory();
rockBand.createGuitar().getGuitar();
rockBand.createBass().getBass();
rockBand.createDrum().getDrum();
System.out.println("--------------------組建一支流行樂隊-----------------------");
PopBankFactory popBand = new PopBankFactory();
popBand.createGuitar().getGuitar();
popBand.createBass().getBass();
popBand.createDrum().getDrum();
}
Output
--------------------組建一支搖滾樂隊-----------------------
Guitar:ESP
Bass:ESP
Drum:Gretsch
--------------------組建一支流行樂隊-----------------------
Guitar:Fender
Bass:Fender
Drum:Roland
4.總結
- 一般抽象工廠模式都是適用於生產多個產品的組合對象時使用
- 抽象工廠模式可以有多個工廠類,有點與簡單工廠相同,不過他可以提供多個產品對象,而不是單一的產品對象
- 如果新增產品,則依然需要修改抽象工廠和具體的工廠類,依舊違反開閉原則