前言 這篇內容是從另一篇:UML建模、設計原則 中分離出來的,原本這個創建型設計模式是和其放在一起的 但是:把這篇創建型設計模式放在一起讓我賊彆扭,看起來賊不舒服,越看念頭越不通達,導致老衲躺在床上腦海中冒出來時都睡不著了 因此:最後實在受不了了,還是將其抽離出來 3、設計模式 分類: 註:使用設計 ...
前言
這篇內容是從另一篇:UML建模、設計原則 中分離出來的,原本這個創建型設計模式是和其放在一起的
但是:把這篇創建型設計模式放在一起讓我賊彆扭,看起來賊不舒服,越看念頭越不通達,導致老衲躺在床上腦海中冒出來時都睡不著了
因此:最後實在受不了了,還是將其抽離出來
3、設計模式
分類:
-
註:使用設計模式的規範,類名 = 需求名+使用的對應設計模式名,如:StringBuilder,這就是使用了Builder建造者模式
-
設計模式不是一成不變的,主要是思想,至於形不需要在意,形只是便於理解罷了
3.1、創建型
這個類型的模式是專門針對於創建對象的,也就是它的適用機制
換言之:這些設計模式提供了一種在創建對象的同時隱藏創建邏輯的方式,而不是使用 new 運算符直接實例化對象
3.1.1、單例模式
定義:保證對象全局唯一,即:保證一個類只有一個實例,哪怕是多線程來進行訪問,向外提供一個訪問此實例的方法即可
使用場景
- 1、資料庫連接池不會反覆創建
- 2、Spring中一個單例模式Bean的創建
- 3、開發中設置一些全局的屬性進行保存(當然:用Redis更好)
3.1.1.1、static實現
package com.zixieqing.o1static;
import java.util.HashMap;
import java.util.Map;
/**
* <p>@description : 該類功能 使用static的方式</p>
* <p>@package : com.zixieqing.o1static</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class StaticSingleton {
private static Map<String, String> CACHE = new HashMap<>();
}
- 這種方式在第一次運行時就初始化Map了,不需要延遲載入
- 缺點:需要被繼承 或 需要維持一些特定狀態時就不適合了
3.1.1.2、懶漢模式
定義:體現在一個“懶”字上,即:需要時才去創建對象
package com.zixieqing.o2lazy;
/**
* <p>@description : 該類功能 懶漢式
* 此種方式不安全:好比多個人搶廁所,會造成不安全,可能有多個人搶到
* </p>
* <p>@package : com.zixieqing.o2lazy</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class LazySingleton {
/**
* 1、private static 當前類的屬性
*/
private static LazySingleton LAZY_SINGLETON_INSTANCE;
/**
* 2、private 的構造
*/
private LazySingleton() {
}
/**
* 3、提供public static 創建當前類的對象的方法
*/
public static LazySingleton getInstance() {
if (null != LAZY_SINGLETON_INSTANCE) return LAZY_SINGLETON_INSTANCE;
LAZY_SINGLETON_INSTANCE = new LazySingleton();
return LAZY_SINGLETON_INSTANCE;
}
/**
* 4、要想稍微安全就加synchronized同步鎖
* 但是:此種方式因為把synchronized加在了方法上,導致所有訪問爭鎖而出現 資源的浪費
*/
/* public static synchronized lazy_unsafe_singleton getInstance() {
if (null != LAZY_UNSAFE_INSTANCE_SINGLETON) return LAZY_UNSAFE_INSTANCE_SINGLETON;
LAZY_UNSAFE_INSTANCE_SINGLETON = new Singleton_lazy_unsafe();
return LAZY_UNSAFE_INSTANCE_SINGLETON;
}*/
}
3.1.1.3、餓漢模式
定義:體現在“餓”字上,即:一開始就初始化
package com.zixieqing.o3hunger;
/**
* <p>@description : 該類功能 餓漢式實現
* 這種方式和利用static的方式是異曲同工的
* </p>
* <p>@package : com.zixieqing.o3hunger</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class HungerSingleton {
private static HungerSingleton HUNGER_SINGLETON_INSTANCE = new HungerSingleton();
private HungerSingleton() {}
/**
* 這種方式其實也不安全
* 因為當多線程在if判斷時如果在同一時刻二者都判斷成立為null,就會創建不同的實例
*/
public static HungerSingleton getInstance() {
if (null != HUNGER_SINGLETON_INSTANCE) return HUNGER_SINGLETON_INSTANCE;
HUNGER_SINGLETON_INSTANCE = new HungerSingleton();
return HUNGER_SINGLETON_INSTANCE;
}
}
3.1.1.4、內部類
package com.zixieqing.o4innerclass;
/**
* <p>@description : 該類功能 使用內部類實現 - 推薦的一種</p>
* <p>@package : com.zixieqing.o4innerclass</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class InnerClassSingleton {
/**
* 1、private的構造
*/
private InnerClassSingleton() {}
/**
* 2、private static的內部類
* 巧妙之處:使用static修飾,則:做到線程安全,也巧妙藉助了第一種實現方式:使用static的形式
* 同時:內部類可以訪問外部類的靜態屬性和靜態方法
*/
private static class NewInstance{
public static InnerClassSingleton INSTANCE = new InnerClassSingleton();
}
/**
* 3、public static對外提供獲取當前類實例的方法
*/
public static InnerClassSingleton getInstance() {
return NewInstance.INSTANCE;
}
}
3.1.1.5、雙重鎖驗證
package com.zixieqing.o5twinlock;
/**
* <p>@description : 該類功能 雙重鎖校驗(線程安全)</p>
* <p>@package : com.zixieqing.o5twinlock</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class TwinLockSingleton {
/**
* 最好加上volatile關鍵字,它的作用是:不進行指令重排(指令重排是JVM中的)
*/
private static volatile TwinLockSingleton INSTANCE;
private TwinLockSingleton() {}
public static TwinLockSingleton getInstance() {
if (null != INSTANCE) return INSTANCE;
// 雙重驗證:synchronized 和 if
synchronized (TwinLockSingleton.class) {
if (null == INSTANCE) return INSTANCE = new TwinLockSingleton();
}
return INSTANCE;
}
}
3.1.1.6、CAS
package com.zixieqing.o6cas;
import java.util.concurrent.atomic.AtomicReference;
/**
* <p>@description : 該類功能 利用CAS演算法實現
* 好處:CAS的忙等演算法是靠底層硬體,所以:保證了線程安全 和 不會產生線程的切換和阻塞的開銷,從而提高性能
* 並且:可以支持較大的併發性
* </p>
* <p>@package : com.zixieqing.o6cas</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class CASSingleton {
private static CASSingleton CAS_SINGLETON_INSTANCE;
/**
* AtomicReference<K> 原子引用 保存“一個”K實例
*/
private static final AtomicReference<CASSingleton> INSTANCE = new AtomicReference<>();
public static CASSingleton getInstance() {
/*
缺點就在這裡:CAS的忙等 從而造成:如果一直沒有獲取就會處於死循壞當中
*/
while (true) {
CAS_SINGLETON_INSTANCE = INSTANCE.get();
if (null != CAS_SINGLETON_INSTANCE) return CAS_SINGLETON_INSTANCE;
/*
boolean compareAndSet(V expect, V update)
expect 預期值
update 要改成的新值
如果當前值和預期值相等,那麼就以原子的方式將值改為新值
下列邏輯:期望INSTANCE是null,所以將INSTANCE的值改為new Singleton_CAS()
*/
INSTANCE.compareAndSet(null, new CASSingleton());
// 獲取INSTANCE的值 返回值就是AtomicReference<Singleton_CAS>中的泛型類型
return INSTANCE.get();
}
}
}
3.1.1.6、枚舉
package com.zixieqing.o7num;
/**
* <p>@description : 該類功能 使用枚舉來實現(極度推薦)
* </p>
* <p>@package : com.zixieqing.o7num</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public enum EnumSingleton {
/**
* 對象
*/
INSTANCE;
/**
* 根據需要自行配置getter也行
*/
}
3.1.2、原型模式
定義:根據一個已有對象(原型實例) 創建 新的對象(就是克隆)
解決的問題:創建重覆對象,而這部分對象本身比較複雜,生成過程從庫或者RPC介面中獲取數據的耗時時長可能會很長,因此:採用克隆的方式會節省時間,總之:當系統中需要創建相同或相似的對象時,就可以用原型模式
場景(在開發中貌似都沒用到過):
- 1、CV大師(
ctrl+c
和ctrl+v
) - 2、JavaSE中的
Object.clone()
瞭解兩個名詞:淺拷貝和深拷貝
- 淺拷貝
- 1、當類的成員變數是基本數據類型時,淺拷貝會將原對象的屬性值賦值給新對象
- 2、當類中成員變數是引用數據類型時,淺拷貝 會將 原對象的引用數據類型的地址 賦值給新對象的成員變數。也就是說 兩個對象共用了同一個數據。當其中一個對象修改成員變數的值時,另外一個的值也會隨之改變
- 深拷貝
- 無論是 基本數據類型還是引用數據類型,都會去開闢額外的空間給新對象
3.1.2.1、用Object.clone() API(不推薦)
3.1.2.1.1、克隆基本數據類型
-
淺拷貝會將原對象的屬性值賦值給新對象(拷貝的是值)
-
註:String底層被final修飾了的,修改值之後是重新創建了一個Sting對象,修改之後不會影響原對象
package com.zixieqing;
/**
* <p>@description : 該類功能 原型類(屬性都是基本數據類型時)
* Cloneable 標誌Object.clone()方法可以對Person該類的實例進行欄位的複製
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Person implements Cloneable{
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person person = null;
try {
person = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return person;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.zixieqing;
/**
* <p>@description : 該類功能 測試
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
person.setName("紫邪情");
Person clonePerson = (Person) person.clone();
System.out.println( "原型對象:" + person);
System.out.println( "克隆對象:" + clonePerson);
clonePerson.setName("小紫");
System.out.println("==========修改之後=============");
System.out.println(person);
System.out.println(clonePerson);
}
}
3.1.2.1.2、克隆引用數據類型
- 淺拷貝 會將 原對象的引用數據類型的地址 賦值給新對象的成員變數(拷貝的是地址)。也就是說 兩個對象共用了同一個數據。當其中一個對象修改成員變數的值時,另外一個的值也會隨之改變
package com.zixieqing;
/**
* <p>@description : 該類功能 原型類(屬性是引用數據類型時)
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Peron2 implements Cloneable{
private Person person;
public Peron2() {
}
public Peron2(Person person) {
this.person = person;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Peron2 peron2 = null;
try {
peron2 = (Peron2) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return peron2;
}
@Override
public String toString() {
return "Peron2{" +
"person=" + person +
'}';
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
package com.zixieqing;
/**
* <p>@description : 該類功能 測試
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Peron2 peron2 = new Peron2();
Person person = new Person("法外狂徒");
peron2.setPerson(person);
Peron2 clonePerson2 = (Peron2) peron2.clone();
System.out.println(peron2);
System.out.println(clonePerson2);
person.setName("張三");
clonePerson2.setPerson(person);
System.out.println("修改之後");
System.out.println(peron2);
System.out.println(clonePerson2);
}
}
3.1.2.2、使用序列化(推薦)
package com.zixieqing.o2useserialize;
import com.zixieqing.o1useclone.Person;
import java.io.*;
/**
* <p>@description : 該類功能 測試
* </p>
* <p>@package : com.zixieqing.o2useserialize</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Test {
public static void main(String[] args) throws IOException {
Person3 person3 = new Person3(0, new Person("紫邪情"));
Person3 cloneInstance = cloneInstance(person3);
System.out.println(person3);
System.out.println(cloneInstance);
cloneInstance.setSex(1);
System.out.println("===========修改之後=============");
System.out.println(person3);
System.out.println(cloneInstance);
}
/**
* <p>@description : 該方法功能 對象序列化克隆
* </p>
* <p>@methodName : cloneInstance</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param person3 要進行序列化克隆的對象
* @return com.zixieqing.o2useserialize.Person3
*/
private static Person3 cloneInstance(Person3 person3) throws IOException {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis;
ObjectInputStream ois;
Person3 person = null;
try {
// 序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(person3);
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
person = (Person3) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != bos) bos.close();
if (null != oos) oos.close();
}
return person;
}
}
* 3.1.3、工廠模式
3.1.3.1、簡單工廠(工廠基礎)
定義:把對類的創建初始化全都交給一個工廠來執行,而用戶不需要關心創建的過程是什麼樣的,只需要告訴工廠,我想要什麼就行了
設計模式中並沒有所謂的簡單工廠,這玩意兒嚴格來說是一種編碼規範,但是:也是學工廠模式的基礎
簡單工廠的角色
- 抽象產品:定義產品的規則,即產品有哪些特性和功能,可以是介面、抽象類、普通類也行(但一般不會這麼乾)
- 具體產品:實現或繼承抽象產品的子類
- 產品工廠:提供創建產品的方法,讓使用者通過該方法獲取產品
3.1.3.1.1、簡單邏輯
開發場景:網上買商品,假設有三種購買方式(前面的數字對應其類型):1、通過優惠卡;2、通過快播兌換卡;3、啥也沒用,直接購買實物商品,根據前面說的三角色來整活
準備工作:依賴導入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- LOGGING begin -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
1、抽象產品:定義規則
package com.zixieqing.o1simplefactory.o1simplelogic;
/**
* <p>@description : 該類功能 抽象產品:購物
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o1simplelogic</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IShopping {
/**
* <p>@description : 該方法功能 發送商品
* </p>
* <p>@methodName : sendCommodity</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param userId 用戶id
* @param goodsName 商品名
*/
void sendCommodity(String userId, String goodsName) throws Exception;
}
2、具體產品:實現或繼承抽象產品的子類
-
優惠卡方式
-
package com.zixieqing.o1simplefactory.o1simplelogic.impl; import com.zixieqing.o1simplefactory.o1simplelogic.IShopping; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p>@description : 該類功能 具體商品:優惠卡 * </p> * <p>@package : com.zixieqing.o1simplefactory.o1simplelogic.impl</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class CouponService implements IShopping { private Logger logger = LoggerFactory.getLogger(CouponService.class); @Override public void sendCommodity(String userId, String goodsName) throws Exception { logger.info("用戶:{},通過優惠卡xxxxxx,購買了:{}", userId, goodsName); } }
-
-
快播兌換卡方式
-
package com.zixieqing.o1simplefactory.o1simplelogic.impl; import com.zixieqing.o1simplefactory.o1simplelogic.IShopping; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p>@description : 該類功能 具體商品:快播兌換卡 * </p> * <p>@package : com.zixieqing.o1simplefactory.o1simplelogic.impl</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class QvodCardService implements IShopping { private Logger logger = LoggerFactory.getLogger(QvodCardService.class); @Override public void sendCommodity(String userId, String goodsName) throws Exception { logger.info("用戶:{},通過快播兌換卡yyyyy,購買了:{}", userId, goodsName); } }
-
-
實物夠買的方式
-
package com.zixieqing.o1simplefactory.o1simplelogic.impl; import com.zixieqing.o1simplefactory.o1simplelogic.IShopping; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p>@description : 該類功能 具體商品:啥也不用,直接實物購買 * </p> * <p>@package : com.zixieqing.o1simplefactory.o1simplelogic.impl</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class GoodsService implements IShopping { private Logger logger = LoggerFactory.getLogger(GoodsService.class); @Override public void sendCommodity(String userId, String goodsName) throws Exception { logger.info("用戶:{},實物購買了:{}", userId, goodsName); } }
-
3、產品工廠:提供創建產品的方法,讓調用者通過該工廠獲取產品
package com.zixieqing.o1simplefactory.o1simplelogic;
import com.zixieqing.o1simplefactory.o1simplelogic.impl.CouponService;
import com.zixieqing.o1simplefactory.o1simplelogic.impl.GoodsService;
import com.zixieqing.o1simplefactory.o1simplelogic.impl.QvodCardService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 該類功能 產品工廠:購物工廠
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o1simplelogic</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class ShoppingFactory {
private Logger logger = LoggerFactory.getLogger(ShoppingFactory.class);
/**
* <p>@description : 該方法功能 購物
* </p>
* <p>@methodName : shopping</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param type 購物方式 1、優惠卡;2、快播兌換卡;3、實物購買
* @return com.zixieqing.o1simplefactory.o1simplelogic.IShopping
*/
public IShopping shopping(Integer type) {
if (null == type) return null;
logger.info("正在揀貨.....");
if (1 == type) return new CouponService();
if (2 == type) return new QvodCardService();
if (3 == type) return new GoodsService();
throw new RuntimeException("不存在的商品服務類型");
}
}
- 註:如果上面這個工廠的方法加上了
static
就變成了靜態工廠(靜態方法能被繼承、但不能被重寫)
4、測試:調用者通過工廠獲取對應產品
package com.zixieqing;
import com.zixieqing.o1simplefactory.o1simplelogic.IShopping;
import com.zixieqing.o1simplefactory.o1simplelogic.ShoppingFactory;
/**
* <p>@description : 該類功能 測試
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class APITest {
public static void main(String[] args) throws Exception{
ShoppingFactory shoppingFactory = new ShoppingFactory();
// 1、優惠卡類型
IShopping shopping_1 = shoppingFactory.shopping(1);
shopping_1.sendCommodity(System.nanoTime()+"", "充氣娃娃");
System.out.println("================華麗的分割線===================");
// 2、快播兌換卡
IShopping shopping_2 = shoppingFactory.shopping(2);
shopping_2.sendCommodity(System.nanoTime()+"", "AI女票");
System.out.println("================華麗的分割線===================");
IShopping shopping_3 = shoppingFactory.shopping(3);
shopping_3.sendCommodity(System.nanoTime()+"", "枸杞");
}
}
上面就是理解簡單工廠的邏輯,總結一丟丟
- 簡單工廠的邏輯:
- 由上圖也可知,簡單工廠優點就是調用者可以免除直接創建產品對象的責任,而僅僅"消費"產品,明確責任邊界,降低耦合性,當然其缺點也很明顯
- 1、違背了開閉原則
- 所以從上圖可知:簡單工廠就是橫向發展(不斷加實現類、工廠類中不斷加邏輯判斷)
- 1、違背了開閉原則
3.1.3.1.2、更加貼合開發場景的邏輯
1、先決條件:先簡單搞個返回結果集的工具類
package com.zixieqing.o1simplefactory.o2complex.util;
/**
* <p>@description : 該類功能 返回結果集工具類
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.util</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class ResultUtil {
/**
* 編碼
*/
private String code;
/**
* 信息
*/
private String info;
public ResultUtil(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
2、優惠卡服務
package com.zixieqing.o1simplefactory.o2complex.coupon;
import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 該類功能 模擬發放優惠券業務
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.coupon</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class CouponService {
private Logger logger = LoggerFactory.getLogger(CouponService.class);
/**
* <p>@description : 該方法功能 發放優惠券
* </p>
* <p>@methodName : sendCoupon</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param uId 用戶id
* @param couponNumber 分配的優惠券號碼
* @param uuid 隨機生成的uuid號
* @return com.zixieqing.o1simplefactory.o2complex.util.ResultUtil
*/
public ResultUtil sendCoupon(String uId, String couponNumber, String uuid) {
logger.info("發放優惠券業務準備啟動..........");
logger.info("用戶:{},獲得了優惠券:{}", uId, uId + couponNumber + uuid);
return new ResultUtil("0000", "優惠券發放成功");
}
}
3、快播兌換卡業務
package com.zixieqing.o1simplefactory.o2complex.qvod;
import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 該類功能 快播兌換卡業務
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.qvod</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class QvodService {
private Logger logger = LoggerFactory.getLogger(QvodService.class);
/**
* <p>@description : 該方法功能 授予兌換卡
* </p>
* <p>@methodName : grentToken</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param phone 用戶手機號
* @param cardId 隨機生成的卡號
* @return com.zixieqing.o1simplefactory.o2complex.util.ResultUtil
*/
public ResultUtil grentToken(String phone, String cardId) {
logger.info("授予的兌換卡為:{}", phone + cardId);
return new ResultUtil("0000", phone + cardId);
}
}
4、實物購買商品業務
-
輔助對象
-
package com.zixieqing.o1simplefactory.o2complex.goods; /** * <p>@description : 該類功能 實物購買:支付要求對象 * </p> * <p>@package : com.zixieqing.o1simplefactory.o2complex.goods</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class DeliverRequest { /** * 用戶姓名 */ private String userName; /** * 用戶手機 */ private String userPhone; /** * 商品SKU:庫存保有單位 */ private String sku; /** * 訂單ID */ private String orderId; /** * 收貨人姓名 */ private String consigneeUserName; /** * 收貨人手機 */ private String consigneeUserPhone; /** * 收穫人地址 */ private String consigneeUserAddress; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPhone() { return userPhone; } public void setUserPhone(String userPhone) { this.userPhone = userPhone; } public String getSku() { return sku; } public void setSku(String sku) { this.sku = sku; } public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; } public String getConsigneeUserName() { return consigneeUserName; } public void setConsigneeUserName(String consigneeUserName) { this.consigneeUserName = consigneeUserName; } public String getConsigneeUserPhone() { return consigneeUserPhone; } public void setConsigneeUserPhone(String consigneeUserPhone) { this.consigneeUserPhone = consigneeUserPhone; } public String getConsigneeUserAddress() { return consigneeUserAddress; } public void setConsigneeUserAddress(String consigneeUserAddress) { this.consigneeUserAddress = consigneeUserAddress; } }
-
-
業務
-
package com.zixieqing.o1simplefactory.o2complex.goods; import com.alibaba.fastjson.JSON; import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p>@description : 該類功能 實物購買商品業務 * </p> * <p>@package : com.zixieqing.o1simplefactory.o2complex.goods</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class GoodsService { private Logger logger = LoggerFactory.getLogger(GoodsService.class); /** * <p>@description : 該方法功能 發貨 * </p> * <p>@methodName : deliverGoods</p> * <p>@author: ZiXieqing</p> * <p>@version: V1.0.0</p> * @param deliverRequest 輔助:支付對象 * @return com.zixieqing.o1simplefactory.o2complex.util.ResultUtil */ public ResultUtil deliverGoods(DeliverRequest deliverRequest) { logger.info("模擬發送實物商品一個:{}", JSON.toJSONString(deliverRequest)); return new ResultUtil("0000", "發貨成功:" + deliverRequest); } }
-
5、抽象產品:定義規則
package com.zixieqing.o1simplefactory.o2complex;
import java.util.Map;
/**
* <p>@description : 該類功能 商品
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface ICommodityService {
/**
* <p>@description : 該方法功能 發送商品
* </p>
* <p>@methodName : sendCommodity</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param uId 用戶id
* @param commodityId 商品id
* @param bizId 業務id
* @param extMap 擴展信息
*/
void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception;
}
6、具體商品:實現或繼承抽象產品的子類
-
優惠卡
-
package com.zixieqing.o1simplefactory.o2complex.impl; import com.zixieqing.o1simplefactory.o2complex.ICommodityService; import com.zixieqing.o1simplefactory.o2complex.coupon.CouponService; import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; import java.util.UUID; /** * <p>@description : 該類功能 TODO * </p> * <p>@package : com.zixieqing.o1simplefactory.o2complex.impl</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class CouponCommodityServiceImpl implements ICommodityService { private Logger logger = LoggerFactory.getLogger(CouponCommodityServiceImpl.class); /** * 模擬@autowried註入 */ private CouponService couponService = new CouponService(); @Override public void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception { ResultUtil result = couponService.sendCoupon(uId, commodityId, UUID.randomUUID().toString()); if (!"0000".equals(result.getCode())) throw new RuntimeException(result.getInfo()); } }
-
-
快播兌換卡
-
package com.zixieqing.o1simplefactory.o2complex.impl; import com.zixieqing.o1simplefactory.o2complex.ICommodityService; import com.zixieqing.o1simplefactory.o2complex.qvod.QvodService; import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; /** * <p>@description : 該類功能 快播兌換卡發貨 * </p> * <p>@package : com.zixieqing.o1simplefactory.o2complex.impl</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class QvodCommodityServiceImpl implements ICommodityService { private Logger logger = LoggerFactory.getLogger(CouponCommodityServiceImpl.class); /** * 模擬註入 */ private QvodService qvodService = new QvodService(); @Override public void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception { // 這裡把電話號碼定死,模擬而已 ResultUtil result = qvodService.grentToken("12345678910", bizId + commodityId); logger.info("通過快播兌換卡:{},獲取商品:{}", bizId + commodityId, commodityId); if (!"0000".equals(result.getCode())) throw new RuntimeException(result.getInfo()); } }
-
-
實物購買
-
package com.zixieqing.o1simplefactory.o2complex.impl; import com.zixieqing.o1simplefactory.o2complex.ICommodityService; import com.zixieqing.o1simplefactory.o2complex.goods.DeliverRequest; import com.zixieqing.o1simplefactory.o2complex.goods.GoodsService; import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; /** * <p>@description : 該類功能 實物購買商品 * </p> * <p>@package : com.zixieqing.o1simplefactory.o2complex.impl</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class GoodsCommodityServiceImpl implements ICommodityService { private Logger logger = LoggerFactory.getLogger(GoodsCommodityServiceImpl.class); /** * 模擬註入 */ private GoodsService goodsService = new GoodsService(); @Override public void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception { DeliverRequest deliverRequest = new DeliverRequest(); // 下麵這些信息去資料庫搞出來 deliverRequest.setUserName("紫邪情"); deliverRequest.setUserPhone("123143124342"); deliverRequest.setSku(commodityId); deliverRequest.setOrderId(bizId); deliverRequest.setConsigneeUserName(extMap.get("consigneeUserName")); deliverRequest.setConsigneeUserPhone(extMap.get("consigneeUserPhone")); deliverRequest.setConsigneeUserAddress(extMap.get("consigneeUserAddress")); ResultUtil result = goodsService.deliverGoods(deliverRequest); if (!"0000".equals(result.getCode())) throw new RuntimeException(result.getInfo()); } }
-
7、產品工廠:提供創建產品的方法,讓調用者通過該方法獲取產品
package com.zixieqing.o1simplefactory.o2complex;
import com.zixieqing.o1simplefactory.o2complex.impl.CouponCommodityServiceImpl;
import com.zixieqing.o1simplefactory.o2complex.impl.GoodsCommodityServiceImpl;
import com.zixieqing.o1simplefactory.o2complex.impl.QvodCommodityServiceImpl;
/**
* <p>@description : 該類功能 產品工廠
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class CommodityFactory {
/**
* <p>@description : 該方法功能 獲取產品
* </p>
* <p>@methodName : getCommodity</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param type 產品類型
* @return com.zixieqing.o1simplefactory.o2complex.ICommodityService
*/
public ICommodityService getCommodity(Integer type) {
if (1 == type) return new CouponCommodityServiceImpl();
if (2 == type) return new QvodCommodityServiceImpl();
if (3 == type) return new GoodsCommodityServiceImpl();
throw new RuntimeException("不合法的商品類型");
}
}
8、測試
package com.zixieqing;
import com.zixieqing.o1simplefactory.o1simplelogic.IShopping;
import com.zixieqing.o1simplefactory.o1simplelogic.ShoppingFactory;
import com.zixieqing.o1simplefactory.o2complex.CommodityFactory;
import com.zixieqing.o1simplefactory.o2complex.ICommodityService;
import java.util.UUID;
/**
* <p>@description : 該類功能 測試
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class APITest {
public static void main(String[] args) throws Exception{
System.out.println("================華麗的分割線:簡單結合業務開發進行測試===================");
CommodityFactory commodityFactory = new CommodityFactory();
// 1、優惠卡類型
ICommodityService commodity_1 = commodityFactory.getCommodity(1);
commodity_1.sendCommodity(System.nanoTime() + "",
System.currentTimeMillis() + "",
UUID.randomUUID() + "",
null);
// 2、快播兌換卡
ICommodityService commodity_2 = commodityFactory.getCommodity(2);
commodity_2.sendCommodity(System.nanoTime() + "",
System.currentTimeMillis() + "",
UUID.randomUUID() + "",
null);
// 3、實物購買
ICommodityService commodity_3 = commodityFactory.getCommodity(3);
HashMap<String, String> extMap = new HashMap<>();
extMap.put("consigneeUserName", "紫邪情");
extMap.put("consigneeUserPhone", "31343214321432");
extMap.put("consigneeUserAddress", "浙江省.杭州市.餘杭區.XX街道.YY小區.324134321431");
commodity_3.sendCommodity(System.nanoTime() + "",
System.currentTimeMillis() + "",
UUID.randomUUID() + "",
extMap);
}
}
3.1.3.1.3、構建出簡單工廠的方式
廢話文學
- 1、思考要創建的幾個實例(具體產品)之間有什麼共通性
- 2、將多個實例的共通性抽取成一個介面(抽象產品)
- 3、使用一個工廠來對創建的實例進行判斷,從而讓調用者根據條件得到想要的實例對象(還可以結合反射來創建對象)
- 4、然後根據下圖進行架構即可
3.1.3.2、工廠方法模式
定義:定義一個創建對象的介面,但由子類(具體工廠)決定要實例化的類是哪一個。工廠方法讓類把實例化推遲到子類
解決的問題:明確地計劃不同條件下創建不同實例時就可以考慮是否採用工廠模式,從而提高擴展性,減少以後的改代碼量
廢話文學:
-
工廠方法模式的角色
- 抽象工廠角色:工廠方法模式的核心,是具體工廠角色必須實現的介面或者繼承的父類
- 具體工廠角色:含有和具體業務邏輯有關的代碼,由業務調用創建對應的具體產品的對象
- 抽象產品角色:是具體產品繼承的父類或者是實現的介面
- 具體產品角色:具體工廠角色所創建的對象就是此角色的實例
-
工廠方法模式這玩意兒其實就是在簡單工廠的基礎上稍微變了一下而已,多了一層罷了(沒什麼是加一層解決不了的,一層不行,那就再來一層),這裡加的這一層就是對業務層再抽象了一下而已
-
簡單工廠是橫向發展(不斷橫向添加實現類),而工廠方法模式本質是為瞭解決簡單工廠模式的問題(違背開閉原則),所以優點和簡單工廠模式一樣,其是縱向發展(不斷縱向添加工廠類+實現類)
-
簡單工廠模式
-
工廠方法模式:
- 從上圖可以看出:工廠方法模式做的是同一類產品(一條流水線開機時不會還搞多產品加工吧),這個點就是和下麵抽象工廠的最大區別(抽象工廠針對的是產品簇)
3.1.3.2.1、Java中使用工廠方法模式的地方
這個東西其實在剛剛前面的代碼中有一個東西就用到了,即:SLF4J日誌門面,前面用了一個LoggerFactory
,它裡面就用到了工廠方法模式
1、進入getLogger()
// 進入getLogger()
private Logger logger = LoggerFactory.getLogger(QvodService.class);
// 得到的代碼
public static Logger getLogger(Class clazz) {
// 進入這裡的getLogger()
return getLogger(clazz.getName());
}
// 得到代碼
public static Logger getLogger(String name) {
// 再看一下getILoggerFactory()
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
// getILoggerFactory()的代碼
public static ILoggerFactory getILoggerFactory() {
if (INITIALIZATION_STATE == 0) {
INITIALIZATION_STATE = 1;
performInitialization();
}
switch(INITIALIZATION_STATE) {
case 1:
// 重點1、static SubstituteLoggerFactory TEMP_FACTORY = new SubstituteLoggerFactory();
return TEMP_FACTORY;
case 2:
throw new IllegalStateException("org.slf4j.LoggerFactory could not be successfully initialized. See also http://www.slf4j.org/codes.html#unsuccessfulInit");
case 3:
return StaticLoggerBinder.getSingleton().getLoggerFactory();
case 4:
// 重點2、static NOPLoggerFactory NOP_FALLBACK_FACTORY = new NOPLoggerFactory();
return NOP_FALLBACK_FACTORY;
default:
throw new IllegalStateException("Unreachable code");
}
}
- 上面的兩個:
TEMP_FACTORY
、NOP_FALLBACK_FACTORY
都實現了ILoggerFactory
2、看一眼ILoggerFactory
// 這個就是根工廠:定義最大規則的那個叼毛
public interface ILoggerFactory {
Logger getLogger(String var1);
}
逆向回來,邏輯就變成如下的樣子
廢話文學
-
在開發中怎麼使用工廠方法模式(下列邏輯不止適用於此模式,創建型、行為型、結構型均適合,瞭解每種類型針對的是對什麼做架構即可,如:是對類中方法、還是類本身等等做架構來進行抽離,最後時間長了一看需求就知道咋個設計了)
-
1、思考自己要創建的幾個實例( 即:具體產品)有什麼共通性
-
2、將共通性抽取出來變成一個介面或抽象類(即:抽象產品)
-
3、思考對每一個實例(產品)弄一個工廠類之後(即:具體工廠),那這幾個工廠類之間又有什麼共通性
-
4、將工廠類的共通性抽取出來變成一個介面(即:抽象工廠)
-
5、當然:再考慮以後應該會在什麼地方添加功能、是否會擴展的話更好,但這一條需要經驗積累
-
6、然後使用下圖方式做架構即可
-
3.1.3.2.2、實例
場景:文件解析,假設有兩種:1、xml文件解析;2、json文件解析
邏輯如下
1、抽象產品
package com.zixieqing.o2factorymethod;
/**
* <p>@description : 該類功能 文件解析器
* </p>
* <p>@package : com.zixieqing.o2factorymethod</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IFileParser {
String parse();
}
2、具體產品
-
json解析
-
package com.zixieqing.o2factorymethod.impl; import com.zixieqing.o2factorymethod.IFileParser; /** * <p>@description : 該類功能 json文件解析器 * </p> * <p>@package : com.zixieqing.o2factorymethod.impl</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class JsonFileParse implements IFileParser { @Override public String parse() { return "這裡就搞json文件解析的邏輯"; } }
-
-
xml解析
-
package com.zixieqing.o2factorymethod.impl; import com.zixieqing.o2factorymethod.IFileParser; /** * <p>@description : 該類功能 xml文件解析器 * </p> * <p>@package : com.zixieqing.o2factorymethod</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class XMLFileParse implements IFileParser { @Override public String parse() { return "這裡就搞xml文件的解析邏輯"; } }
-
3、抽象工廠
package com.zixieqing.o2factorymethod.factory;
import com.zixieqing.o2factorymethod.IFileParser;
/**
* <p>@description : 該類功能 解析器抽象工廠
* </p>
* <p>@package : com.zixieqing.o2factorymethod</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IParserFactory {
IFileParser parse();
}
4、具體工廠
-
json解析工廠
-
package com.zixieqing.o2factorymethod.factory.impl; import com.zixieqing.o2factorymethod.IFileParser; import com.zixieqing.o2factorymethod.factory.IParserFactory; import com.zixieqing.o2factorymethod.impl.JsonFileParse; /** * <p>@description : 該類功能 json解析工廠 * </p> * <p>@package : com.zixieqing.o2factorymethod.factory</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class JsonParseFactory implements IParserFactory { @Override public IFileParser parse() { return new JsonFileParse(); } }
-
-
xml解析工廠
-
package com.zixieqing.o2factorymethod.factory.impl; import com.zixieqing.o2factorymethod.IFileParser; import com.zixieqing.o2factorymethod.factory.IParserFactory; import com.zixieqing.o2factorymethod.impl.XMLFileParse; /** * <p>@description : 該類功能 xml解析工廠 * </p> * <p>@package : com.zixieqing.o2factorymethod.factory</p> * <p>@author : ZiXieqing</p> * <p>@version : V1.0.0</p> */ public class XMLParseFactory implements IParserFactory { @Override public IFileParser parse() { return new XMLFileParse(); } }
-
3.1.3.3、抽象工廠模式
定義:在工廠方法模式的基礎上,對工廠進行變化一下
解決的問題:產品簇的問題(一個中心工廠來創建其他工廠)
對於產品簇百度有一個通俗易懂的解釋:指具有相同或相似的功能結構或性能,共用主要的產品特征、組件或子結構,並通過變型配置來滿足特定市場的一組產品的聚類
廢話文學對產品簇的解釋:產品簇是指工廠生產出的產品們之間彼此具備強關聯。比如:AK47工廠生產的 AK47步槍、AK47專配的子彈,一旦 AK47裝錯了子彈是無法正常開槍的(甚至會炸膛)
抽象工廠模式的角色
- 抽象工廠角色:工廠方法模式的核心,是具體工廠角色必須實現的介面或者繼承的父類
- 具體工廠角色:含有和具體業務邏輯有關的代碼,由業務調用創建對應的具體產品的對象
- 抽象產品角色:是具體產品繼承的父類或者是實現的介面
- 具體產品角色:具體工廠角色所創建的對象就是此角色的實例
抽象工廠模式邏輯舉例(上面的四角色自行對應)
3.1.3.3.1、簡單邏輯實現
就用上面說的傢具來舉例
1、椅子介面(抽象產品)
package com.zixieqing.o3abstractfactory;
/**
* <p>@description : 該類功能 抽象產品:椅子介面
* </p>
* <p>@package : com.zixieqing.o3abstractfactory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IChair {
/**
* <p>@description : 該方法功能 生產椅子
* </p>
* <p>@methodName : createChair</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
*
* @return java.lang.String
*/
String create();
}
- 1.1、木質桌子(具體產品)
package com.zixieqing.o3abstractfactory.impl;
import com.zixieqing.o3abstractfactory.IChair;
/**
* <p>@description : 該類功能 具體產品:木質椅子
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class WoodenChair implements IChair {
@Override
public String create() {
return "木質椅子";
}
}
- 1.2、塑料桌子(具體產品)
package com.zixieqing.o3abstractfactory.impl;
import com.zixieqing.o3abstractfactory.IChair;
/**
* <p>@description : 該類功能 具體產品:塑料椅子
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class PlasticChair implements IChair {
@Override
public String create() {
return "塑料椅子";
}
}
2、桌子介面(抽象產品)
package com.zixieqing.o3abstractfactory;
/**
* <p>@description : 該類功能 抽象產品:桌子介面
* </p>
* <p>@package : com.zixieqing.o3abstractfactory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IDesk {
/**
* <p>@description : 該方法功能 生產桌子
* </p>
* <p>@methodName : create</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
*
* @return java.lang.String
*/
String create();
}
- 木質桌子
package com.zixieqing.o3abstractfactory.impl;
import com.zixieqing.o3abstractfactory.IDesk;
/**
* <p>@description : 該類功能 具體產品:木質桌子
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class WoodenDesk implements IDesk {
@Override
public String create() {
return "木質桌子";
}
}
- 塑料桌子
package com.zixieqing.o3abstractfactory.impl;
import com.zixieqing.o3abstractfactory.IDesk;
/**
* <p>@description : 該類功能 具體產品:塑料桌子
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class PlastidDeck implements IDesk {
@Override
public String create() {
return "塑料桌子";
}
}
3、傢具抽象工廠
package com.zixieqing.o3abstractfactory;
/**
* <p>@description : 該類功能 抽象工廠:傢具工廠
* </p>
* <p>@package : com.zixieqing.o3abstractfactory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IFurnitureFactory {
IChair createChair();
IDesk createDesk();
}
- 木質傢具工廠
package com.zixieqing.o3abstractfactory.factory;
import com.zixieqing.o3abstractfactory.IChair;
import com.zixieqing.o3abstractfactory.IDesk;
import com.zixieqing.o3abstractfactory.IFurnitureFactory;
import com.zixieqing.o3abstractfactory.impl.WoodenChair;
import com.zixieqing.o3abstractfactory.impl.WoodenDesk;
/**
* <p>@description : 該類功能 具體工廠:專門生產木質傢具這一產品簇需要的東西
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.factory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class WoodenIFurnitureFactory implements IFurnitureFactory {
@Override
public IChair createChair() {
return new WoodenChair();
}
@Override
public IDesk createDesk() {
return new WoodenDesk();
}
}
- 塑料傢具工廠
package com.zixieqing.o3abstractfactory.factory;
import com.zixieqing.o3abstractfactory.IChair;
import com.zixieqing.o3abstractfactory.IDesk;
import com.zixieqing.o3abstractfactory.IFurnitureFactory;
import com.zixieqing.o3abstractfactory.impl.PlasticChair;
import com.zixieqing.o3abstractfactory.impl.PlastidDeck;
/**
* <p>@description : 該類功能 具體工廠:專門生產塑料傢具這一產品簇需要的東西
* </p>
* <p>@package : com.zixieqing.o3abstractfactory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class PlasticFurnitureFactory implements IFurnitureFactory {
@Override
public IChair createChair() {
return new PlasticChair();
}
@Override
public IDesk createDesk() {
return new PlastidDeck();
}
}
4、測試
package com.zixieqing;
import com.zixieqing.o3abstractfactory.factory.PlasticFurnitureFactory;
import com.zixieqing.o3abstractfactory.factory.WoodenIFurnitureFactory;
/**
* <p>@description : 該類功能 測試
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class AbstractFactoryTest {
public static void main(String[] args) {
// 木質椅子
String chair = new WoodenIFurnitureFactory().createChair().create();