目錄
- 基本介紹
- 簡單工廠模式
- 工廠方法模式
- 抽象工廠模式
基本介紹
- 工廠模式:屬于創建模式的一種,仔細劃分的話,工廠模式大致分為三種,簡單工廠模式、工廠方法模式以及抽象工廠模式,
- 主要作用:創建物件時避免客戶端直接暴露創建邏輯(解耦),而是通過一個公共的介面去創建物件,
- 優點:①. 擴展性好,想增加產品,只要擴展相應工廠類即可,(也是缺點)②. 屏蔽產品的具體實作細節

簡單工廠模式
基于上圖說的場景,我們了解所有的英雄和英雄皮膚都可以被購買,那么我們先定義一個介面讓所有英雄和英雄皮膚遵循這個規則
public interface Hero {
/**
* 成功購買英雄
*/
void buyHeroSuccess();
/**
* 成功購買配套皮膚
*/
void buySkinSuccess();
}
那么接下來我們開始定義不同的英雄,這里我們分別選 妲己、程咬金、后羿 作為示例
/**
* 妲己
*/
public class DaJi implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-妲己!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了皮膚-熱情桑巴");
}
}
/**
* 程咬金
*/
public class ChengYaoJin implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-程咬金!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了皮膚-愛與正義");
}
}
/**
* 后羿
*/
public class HouYi implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-后羿!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了皮膚-黃金射手座");
}
}
上面我們一下子就定義了三個英雄,下面就可以開始簡單工廠的核心了-工廠
既然是工廠模式,那么生產產品的時候(即創建類),由工廠統一管理,我們通過標簽去決定生產什么樣的產品
/**
* 王者榮耀工廠(商城)
*/
public class HerosFactory {
/**
* 根據不同的標簽生產不同的英雄
*/
public Hero getDifferentHero(String heroType) {
if("HouYi".equals(heroType)){
return new HouYi();
}else if("DaJi".equals(heroType)){
return new DaJi();
}else if("ChengYaoJin".equals(heroType)){
return new ChengYaoJin();
}
return null;
}
}
寫完了簡單工廠的工廠類,我們可以寫個測驗方法測驗一下
/**
* 測驗方法
*/
public class TestFactory {
public static void main(String[] args) {
HerosFactory herosFactory = new HerosFactory();
Hero hero1 = herosFactory.getDifferentHero("DaJi");
hero1.buyHeroSuccess();
hero1.buySkinSuccess();
System.out.println("-----------------");
Hero hero2 = herosFactory.getDifferentHero("HouYi");
hero2.buyHeroSuccess();
hero2.buySkinSuccess();
}
}

工廠方法模式
我個人認為工廠方法模式是簡單工廠模式的升級,我們先想想簡單工廠模式最大的缺點是啥?
如果我想新增一個物件,那么我就需要擴展工廠類,即我需要去改工廠類的生產方法代碼去增加一個標簽
這么干,實際違背了 開閉原則-對外擴展開放,對內修改關閉
比較好的方案是什么呢?
再定義一個抽象的工廠型別的基類,讓子類去實作該基類(也就是工廠與實體物件遙相呼應),可能這么說,還是有人不明白,上代碼
首先英雄介面部分還是和簡單工廠一致
public interface Hero {
/**
* 成功購買英雄
*/
void buyHeroSuccess();
/**
* 成功購買配套皮膚
*/
void buySkinSuccess();
}
接著我們是已購買三個英雄,妲己、程咬金、后羿
/**
* 妲己
*/
public class DaJi implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-妲己!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了皮膚-熱情桑巴");
}
}
/**
* 程咬金
*/
public class ChengYaoJin implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-程咬金!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了皮膚-愛與正義");
}
}
/**
* 后羿
*/
public class HouYi implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-后羿!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了皮膚-黃金射手座");
}
}
上述代碼都是和簡單工廠部分一致,針對我們說的問題,我們說 定義一個抽象的工廠型別的基類
/**
* 工廠方法模式:(王者榮耀商城)
*/
public abstract class HeroFactory {
protected abstract Hero productHero();
}
我們已經看到了,基類的抽象方法可以創建英雄,那么需要創建的子類工廠通過繼承該基類就可以完成創建所需英雄的功能了
/**
* 定義一個射手英雄工廠
*/
public class ArrowFactory extends HeroFactory{
@Override
protected Hero productHero() {
return new HouYi();
}
}
/**
* 法師工廠
*/
public class MageFactory extends HeroFactory{
@Override
protected Hero productHero() {
return new DaJi();
}
}
/**
* 坦克工廠
*/
public class TanksFactory extends HeroFactory{
@Override
protected Hero productHero() {
return new ChengYaoJin();
}
}
定義完三個工廠,我們再次進行測驗
/**
* 測驗工廠方法模式
*/
public class TestFatcoryMethod {
public static void main(String[] args) {
Hero hero1 = new ArrowFactory().productHero();
hero1.buyHeroSuccess();
hero1.buySkinSuccess();
System.out.println("------------");
Hero hero2 = new MageFactory().productHero();
hero2.buyHeroSuccess();
hero2.buySkinSuccess();
}
}

抽象工廠模式
抽象工廠模式是所有形態的工廠模式中最為抽象和最具一般性的一種形態模式,(不然怎么叫抽象工廠)
其次抽象工廠是指當有多個抽象角色,使用一種工廠模式,抽象工廠可以向提供一個介面,使客戶端在不指定產品的具體情況下,創建多個產品族中的物件,一個抽象工廠類,可以派生多個具體工廠類,每個具體的工廠類可以創建多個產品的實體,
工廠方法模式 是對 一個產品型別進行構建,而抽象工廠則針對的 是 多個產品型別的構建,
下面我們用代碼去演繹抽象工廠模式:
之前說過王者榮耀商城中,可以買英雄和皮膚,按照面向物件的思想我們可以將英雄 和 皮膚 單獨抽取,成為最頂層的介面,那么會有下面的代碼:
//英雄的頂層介面
public interface Hero {
void haveHero();
}
定義完第一個抽象角色,也就是英雄的頂層介面,接下來我們定義具體的實作
/**
* 妲己
*/
public class DaJiHero implements Hero {
@Override
public void haveHero() {
System.out.println("勇士,恭喜你已獲得-妲己");
}
}
/**
* 程咬金
*/
public class ChengYaoJinHero implements Hero {
@Override
public void haveHero() {
System.out.println("勇士,恭喜你已獲得-程咬金");
}
}
/**
* 后羿
*/
public class HouYiHero implements Hero {
@Override
public void haveHero() {
System.out.println("勇士,恭喜你獲得了英雄-后羿");
}
}
我們知道英雄還有皮膚,所以我們定義第二個抽象角色,即皮膚的頂層介面
/**
* 皮膚
*/
public interface Skin {
void haveSkin();
}
接著定義皮膚介面的實作類
/**
* 妲己皮膚
*/
public class DaJiSkin implements Skin{
@Override
public void haveSkin() {
System.out.println("恭喜你獲得了皮膚-熱情桑巴");
}
}
/**
* 程咬金皮膚
*/
public class ChengYaoJinSkin implements Skin {
@Override
public void haveSkin() {
System.out.println("恭喜你獲得了皮膚-愛與正義");
}
}
/**
* 后羿皮膚
*/
public class HouYiSkin implements Skin{
@Override
public void haveSkin() {
System.out.println("恭喜你獲得了皮膚-黃金射手座");
}
}
根據上面的概念,我們定義完了2個抽象角色,那么還需定義一個抽象工廠,可能你會問為什么要定義一個抽象工廠,因為上面的概念也說到了定義抽象工廠的目的就是為了派生具體的工廠類(也就是讓子類去實作),這個抽象工廠類加上abstract 關鍵字后,又該如何去寫內部的邏輯,我想這一塊才是最需要思考和解決的問題,
/**
* 商品工廠(頂層多型介面 )
*/
public interface MarketFactory {
}
/**
* 英雄抽象工廠
*/
public abstract class HeroAbStractFactory implements MarketFactory {
public abstract Hero getHero(String heroType);
}
/**
* 皮膚抽象工廠
*/
public abstract class SkinAbStractFactory implements MarketFactory {
public abstract Skin getSkin(String skinType);
}
定義完抽象工廠,我們實作兩個工廠
/**
* 英雄工廠
*/
public class HeroFactory extends HeroAbStractFactory {
@Override
public Hero getHero(String heroType) {
if("HouYi".equals(heroType)){
return new HouYiHero();
}else if("DaJi".equals(heroType)){
return new DaJiHero();
}else if("ChengYaoJin".equals(heroType)){
return new ChengYaoJinHero();
}
return null;
}
}
/**
* 皮膚工廠
*/
public class SkinFactory extends SkinAbStractFactory {
@Override
public Skin getSkin(String skinType) {
if("HouYi".equals(skinType)){
return new HouYiSkin();
}else if("DaJi".equals(skinType)){
return new DaJiSkin();
}else if("ChengYaoJin".equals(skinType)){
return new ChengYaoJinSkin();
}
return null;
}
}
那么,我們已經定義完具體的實體工廠,一個是英雄工廠,一個是皮膚工廠,現在可以定義一個統一管理類管理這兩個工廠
/**
* 工廠(商城)
*/
public class FactoryProduct {
public static MarketFactory getFactoryByType(String factoryType){
if("HeroFactory".equals(factoryType)){
return new HeroFactory();
}else if("SkinFactory".equals(factoryType)){
return new SkinFactory();
}
return null;
}
}
最后我們開始測驗
/**
* 工廠測驗
*/
public class TestFactory {
public static void main(String[] args) {
HeroFactory heroFactory = (HeroFactory) FactoryProduct.getFactoryByType("HeroFactory");
Hero hero = heroFactory.getHero("ChengYaoJin");
hero.haveHero();
SkinFactory skinFactory = (SkinFactory) FactoryProduct.getFactoryByType("SkinFactory");
Skin skin = skinFactory.getSkin("ChengYaoJin");
skin.haveSkin();
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/4548.html
標籤:設計模式
上一篇:設計模式(6) 配接器模式
下一篇:單例模式
