實現建立者與調用者的分離編程
以化妝品爲例:atom
生產者:spa
一個接口,提供了生產化妝品的方法設計
public interface Cosmetics {
void productCosmetics();
}
生產的對象:對象
口紅blog
public class Lipstick implements Cosmetics{
public void productCosmetics() {
System.out.println("口紅");
}
}
眼影繼承
public class EyeShadow implements Cosmetics{
public void productCosmetics() {
System.out.println("眼影");
}
}
圖解接口
消費者:ip
消費者要首先把 Lipstick 和 EyeShadow 實例化(new),才能實現對象的方法。get
public class Consumer {
public static void main(String[] args) {
Cosmetics lipstick = new Lipstick();
Cosmetics eyeShadow = new EyeShadow();
lipstick.productCosmetics();
eyeShadow.productCosmetics();
}
}
圖解
化妝品工廠
public class CosmeticsFactory {
public static Cosmetics getCosmeticsFactory(String factory){
if (factory.equals("口紅")){
return new Lipstick();
}else if (factory.equals("眼影")){
return new EyeShadow();
}else {
return null;
}
}
}
消費者:
經過化妝品工廠來獲得對象的實例化,無需new,來實現對象的方法
public class Consumer {
public static void main(String[] args) {
Cosmetics lipstick = CosmeticsFactory.getCosmeticsFactory("口紅");
lipstick.productCosmetics();
Cosmetics eyeShadow = CosmeticsFactory.getCosmeticsFactory("眼影");
eyeShadow.productCosmetics();
}
}
工廠模式缺點:
OOP七大原則之開閉原則:一個軟件的實體應對擴展開放,對修改關閉
工廠模式實現不了開閉原則,若是要擴展新的功能,必須修改CosmeticsFactory才能實現
解決工廠模式沒法實現開閉原則的問題
圖解
化妝品工廠
public interface CosmeticsFactory {
Cosmetics getCosmetics();
}
口紅工廠
public class LipstickFactory implements CosmeticsFactory {
public Cosmetics getCosmetics() {
return new Lipstick();
}
}
眼影工廠
public class EyeShadowFactory implements CosmeticsFactory {
public Cosmetics getCosmetics() {
return new EyeShadow();
}
}
消費者
public class Consumer {
public static void main(String[] args) {
Cosmetics lipstick = new LipstickFactory().getCosmetics();
lipstick.productCosmetics();
Cosmetics eyeShadow = new EyeShadowFactory().getCosmetics();
eyeShadow.productCosmetics();
}
}
新增一個產品:
只須要編寫一個產品類,例如眉筆,編寫一個眉筆工廠繼承化妝品工廠,
可在不改動原有代碼的基礎上擴展功能,實現開閉原則。
簡單工廠模式 和 工廠方法模式 都是用來生產同一等級結構的任意產品
抽象工廠模式 統一建立同一系列的產品,能夠建立多個產品家族的多個等級結構的產品
圖解
實現
產品工廠:
public interface ProductFactory {
//生產手機
Phone productPhone();
//生產電腦
Computer productComputer();
}
手機:
public interface Phone {
//生產手機屏
void productMobileScreen();
//生產手機外殼
void productPhoneShell();
//生產手機套
void productPhoneSet();
}
電腦:
public interface Computer {
//生產電腦屏
void productMobileScreen();
//生產電腦外殼
void productPhoneShell();
//生產電腦套
void productPhoneSet();
}
HUAWEI產品工廠:
public class HUAWEIProductFactory implements ProductFactory {
//實例化HUAWEI手機
public Phone productPhone() {
return new HUAWEIPhone();
}
//實例化HUAWEI電腦
public Computer productComputer() {
return new HUAWEIComputer();
}
}
ASUS產品工廠:
public class ASUSProductFactory implements ProductFactory {
//實例化ASUS手機
public Phone productPhone() {
return new ASUSPhone();
}
//實例化ASUS電腦
public Computer productComputer() {
return new ASUSComputer();
}
}
HUAWEI手機:
public class HUAWEIPhone implements Phone {
public void productMobileScreen() {
System.out.println("生產HUAWEI手機屏");
}
public void productPhoneShell() {
System.out.println("生產HUAWEI手機外殼");
}
public void productPhoneSet() {
System.out.println("生產HUAWEI手機套");
}
}
ASUS手機:
public class ASUSPhone implements Phone {
public void productMobileScreen() {
System.out.println("生產ASUS手機屏");
}
public void productPhoneShell() {
System.out.println("生產ASUS手機外殼");
}
public void productPhoneSet() {
System.out.println("生產ASUS手機套");
}
}
HUAWEI電腦:
public class HUAWEIComputer implements Computer {
public void productMobileScreen() {
System.out.println("生產HUAWEI電腦屏");
}
public void productPhoneShell() {
System.out.println("生產HUAWEI電腦外殼");
}
public void productPhoneSet() {
System.out.println("生產HUAWEI電腦套");
}
}
ASUS電腦:
public class ASUSComputer implements Computer {
public void productMobileScreen() {
System.out.println("生產ASUS電腦屏");
}
public void productPhoneShell() {
System.out.println("生產ASUS電腦外殼");
}
public void productPhoneSet() {
System.out.println("生產ASUS電腦套");
}
}
消費者:
public class Consumer {
public static void main(String[] args) {
//消費者直接操做HUAWEI和ASUS的產品工廠
HUAWEIProductFactory huaweiProductFactory = new HUAWEIProductFactory();
ASUSProductFactory asusProductFactory = new ASUSProductFactory();
//經過工廠生產手機和電腦
//huawei電腦
Computer huaweiComputer = huaweiProductFactory.productComputer();
//asus手機
Phone asusPhone = asusProductFactory.productPhone();
//調用生產的手機和電腦中的方法,操做手機和電腦
huaweiComputer.productMobileScreen();
huaweiComputer.productPhoneShell();
asusPhone.productPhoneShell();
asusPhone.productPhoneSet();
}
}
優勢:
具體產品在應用層的代碼隔離,無需關心建立的細節
將同一系列的產品統一到一塊兒建立
缺點:
產品簇中擴展新的產品困難
增長了系統的抽象性和理解難度
簡單工廠模式
雖然沒有實現開閉原則,但實際使用最多
工廠方法模式
不修改已有類的前提下,能夠增長新的工廠類進行擴展
抽象工廠模式
不能夠增長產品,能夠增長產品族
三種模式對比
代碼複雜度:簡單工廠模式 < 工廠方法模式 < 抽象工廠模式
結構複雜度:簡單工廠模式 < 工廠方法模式 < 抽象工廠模式
編程複雜度:簡單工廠模式 < 工廠方法模式 < 抽象工廠模式
管理複雜度:簡單工廠模式 < 工廠方法模式 < 抽象工廠模式
根據設計原則,應使用工廠方法模式
根據實際業務,工廠方法模式使用最多
工廠模式應用場景:
JDK中的Calenda的getInstance()方法
JDBC中的Connection對象的獲取
Spring中IOC容器建立管理bean對象