工廠模式
簡(jiǎn)單工廠模式
工廠方法模式
抽象工廠模式
1.簡(jiǎn)單工廠模式
1.基本介紹
1)簡(jiǎn)單工廠模式也叫靜態(tài)工廠模式饱普,是屬于創(chuàng)建型模式,是工廠模式的一種焕议,簡(jiǎn)單工廠模式是由一個(gè)工廠對(duì)象決定創(chuàng)建哪一種產(chǎn)品類的實(shí)例设哗。簡(jiǎn)單工廠模式是工廠模式種最簡(jiǎn)單實(shí)用的模式。
2)簡(jiǎn)單工廠模式:定義了一個(gè)創(chuàng)建對(duì)象的類抠蚣,由這個(gè)類來封裝實(shí)例化對(duì)象的行為
3)在軟件開發(fā)中,當(dāng)我們會(huì)用到大量的創(chuàng)建某種履澳、某類或者某批對(duì)象時(shí)嘶窄,就會(huì)使用到工廠模式.
2.解決的問題
將"類實(shí)例化的操作"與''使用對(duì)象的操作"分開,讓使用者不需要知道具體參數(shù)就可以實(shí)例化出所需要的''產(chǎn)品''類距贷,從而避免了在客戶段種顯示指定柄冲,實(shí)現(xiàn)了解耦,即使用者可以直接消費(fèi)產(chǎn)品而不需要知道其生產(chǎn)的細(xì)節(jié)忠蝗。
3.模式的組成
抽象產(chǎn)品(Product):描述產(chǎn)品的公共接口现横,是具體產(chǎn)品的父類。
具體產(chǎn)品(ConcreteProduct):描述生產(chǎn)的具體產(chǎn)品阁最,抽象產(chǎn)品的子類戒祠,工廠類創(chuàng)建的目標(biāo)類。
工廠(Factory):根據(jù)傳入不同的參數(shù)從而創(chuàng)建不同具體產(chǎn)品類的實(shí)例速种,被外界調(diào)用姜盈。
4.使用步驟
- 創(chuàng)建抽象產(chǎn)品類&定義具體產(chǎn)品的公共接口;
- 創(chuàng)建具體產(chǎn)品類(繼承抽象產(chǎn)品類)配阵,定義生產(chǎn)的具體產(chǎn)品馏颂;
- 創(chuàng)建工廠類,通過創(chuàng)建靜態(tài)方法更具傳入不同參數(shù)從而創(chuàng)建不同具體產(chǎn)品類的實(shí)例棋傍。
- 外界通過調(diào)用工廠類的靜態(tài)方法救拉,傳入不同參數(shù)從而創(chuàng)建不同具體產(chǎn)品類的實(shí)例。
5.優(yōu)點(diǎn)
- 將創(chuàng)建實(shí)例的工作與使用實(shí)例的工作分開舍沙,使用者不必關(guān)心類對(duì)象如何創(chuàng)建近上,實(shí)現(xiàn)了解耦。
- 把初始化實(shí)列時(shí)的工作放到工廠里進(jìn)行拂铡,是代碼更容易維護(hù)壹无。更符合面向?qū)ο蟮脑瓌t。
5.缺點(diǎn)
- 工廠類集中了所有實(shí)例(產(chǎn)品)的創(chuàng)建邏輯感帅,一旦這個(gè)工廠不能正常工作斗锭,整個(gè)系統(tǒng)都會(huì)受到影響。
- 違背”開發(fā)封閉原則“失球,一旦添加新產(chǎn)品就不得不修改工廠類的邏輯岖是,這樣就會(huì)造成工廠邏輯過于復(fù)雜帮毁。
- 簡(jiǎn)單工廠模式由于使用了靜態(tài)工廠方法,靜態(tài)方法不能被繼承和重寫豺撑,會(huì)造成工廠角色無法形成基于繼承的等級(jí)結(jié)構(gòu)烈疚。
6.示例
目的:奶茶店有三種奶茶原味,珍珠和紅豆聪轿,老板希望使用簡(jiǎn)單工廠模式生產(chǎn)這>三種奶茶爷肝。
代碼:
public class SampleFactoryPattern {
public static void main(String[] args) {
Factor.makeProduct("紅豆").make();;
Factor.makeProduct("珍珠").make();;
Factor.makeProduct("原味").make();;
}
}
//1.創(chuàng)建抽象產(chǎn)品類,定義具體用戶點(diǎn)單的公共接口
interface Product{
public void make();
}
//2.創(chuàng)建具體產(chǎn)品類(實(shí)現(xiàn)接口),定義生產(chǎn)的具體產(chǎn)品
class ProductPlain implements Product{
//原味奶茶
@Override
public void make() {
System.out.println("生產(chǎn)了原味奶茶");
}
}
class ProductPearl implements Product{
//珍珠奶茶
@Override
public void make() {
System.out.println("生產(chǎn)了珍珠奶茶");
}
}
class ProductRedBeans implements Product{
//紅豆奶茶
@Override
public void make() {
System.out.println("生產(chǎn)了紅豆奶茶");
}
}
//3.創(chuàng)建工廠類陆错,通過創(chuàng)建靜態(tài)方法從而根據(jù)傳入不同參數(shù)創(chuàng)建不同具體產(chǎn)品類的實(shí)例灯抛。
class Factor{
public static Product makeProduct(String name) {
switch(name) {
case "原味":
return new ProductPlain();
case "珍珠":
return new ProductPearl();
case "紅豆":
return new ProductRedBeans();
default:
return null;
}
}
}
截圖:
2.工廠方法模式
1.基本介紹
工廠方法模式:定義了一個(gè)創(chuàng)建對(duì)象的抽象方法,由子類決定要實(shí)例化的類音瓷。工廠方法模式將對(duì)象的實(shí)例化推遲到子類对嚼。
2.主要作用
將類的實(shí)例化(具體產(chǎn)品的創(chuàng)建)延遲到工廠類的子類(具體工廠)種完成,即由子類決定應(yīng)用實(shí)例(創(chuàng)建)哪一個(gè)類绳慎。
3.解決的問題
簡(jiǎn)單工廠模式的缺點(diǎn)纵竖,工廠一旦創(chuàng)建需要生產(chǎn)新產(chǎn)品就需要修改工廠類的方法邏輯,違背了"開放封閉原則"杏愤。
之所以可以解決簡(jiǎn)單工廠的問題磨确,是因?yàn)楣S方法模式把具體產(chǎn)品的創(chuàng)建推出到工廠類的子類(具體工廠)中,此時(shí)工廠類不再負(fù)責(zé)所有產(chǎn)品的創(chuàng)建声邦,而是給出具體工廠必須實(shí)現(xiàn)的接口,這樣工廠方法模式再添加新產(chǎn)品的時(shí)候就不修改工廠類邏輯而是添加新的工廠子類摆舟,符合開放封閉原則亥曹,克服了簡(jiǎn)單工廠模式中的缺點(diǎn)。
4.模式的組成
抽象產(chǎn)品(Product):描述產(chǎn)品的公共接口恨诱,是具體產(chǎn)品的父類媳瞪。
具體產(chǎn)品(ConcreteProduct):描述生產(chǎn)的具體產(chǎn)品,抽象產(chǎn)品的子類照宝,工廠類創(chuàng)建的目標(biāo)類蛇受,描述的具體產(chǎn)品。
抽象工廠(Factory):描述具體工廠的公共接口厕鹃,具體工廠的父類兢仰。
具體工廠(ConcreteCreator):實(shí)現(xiàn)FactoryMethod工廠方法創(chuàng)建產(chǎn)品的實(shí)例,抽象工廠的子類剂碴,被外界調(diào)用把将。
5.使用步驟
1.創(chuàng)建抽象工廠類,定義具體工廠的公共接口忆矛;
2.創(chuàng)建抽象產(chǎn)品類察蹲,定義具體產(chǎn)品的公共接口
3.創(chuàng)建具體產(chǎn)品類(繼承抽象產(chǎn)品類或者實(shí)現(xiàn)接口),定義生產(chǎn)的具體產(chǎn)品;
4.創(chuàng)建具體工廠類(繼承抽象工廠類或者實(shí)現(xiàn)接口)洽议,定義創(chuàng)建對(duì)應(yīng)具體產(chǎn)品實(shí)例的方法宗收。
5.外界通過調(diào)用具體工廠類的放,從而創(chuàng)建不同具體產(chǎn)品類的實(shí)例亚兄。
6.優(yōu)點(diǎn)
更符合開放封閉原則混稽,新增一種產(chǎn)品時(shí),只需要增加相應(yīng)的具體產(chǎn)品類和相應(yīng)的工廠子類即可儿捧,無需修改荚坞。
符合單一職責(zé)原則,每個(gè)具體工廠類只負(fù)責(zé)創(chuàng)建對(duì)應(yīng)的產(chǎn)品菲盾。
不使用靜態(tài)工廠方法颓影,可以形成基本繼承的等級(jí)結(jié)構(gòu)。
工廠模式可以說時(shí)簡(jiǎn)單工廠模式的進(jìn)一步抽象和拓展懒鉴,在保留了簡(jiǎn)單工廠封裝的優(yōu)點(diǎn)的同時(shí)诡挂,讓擴(kuò)展變得更加簡(jiǎn)單,讓繼承變得可行临谱,增加了多態(tài)性得體現(xiàn)璃俗。
7.缺點(diǎn)
添加新產(chǎn)品時(shí),除了增加新產(chǎn)品類外悉默,還要提供與之對(duì)應(yīng)的具體工廠類城豁,系統(tǒng)類的個(gè)數(shù)將成對(duì)增加,在一定程度上增加了系統(tǒng)的復(fù)雜度抄课;同時(shí)唱星,有更多的類需要編譯和運(yùn)行,會(huì)給系統(tǒng)帶來一些額外的開銷跟磨;
·由于考慮到系統(tǒng)的可擴(kuò)展性间聊,需要引入抽象層,在客戶端代碼中均使用抽象層進(jìn)行定義抵拘,增加了系統(tǒng)的抽象性和理解難度哎榴,且在實(shí)現(xiàn)時(shí)可能需要用到DOM、反射等技術(shù)僵蛛,增加了系統(tǒng)的實(shí)現(xiàn)難度尚蝌。
·雖然保證了工廠方法內(nèi)的對(duì)修改關(guān)閉,但對(duì)于使用工廠方法的類充尉,如果要更換另外一種產(chǎn)品驼壶,仍然需要修改實(shí)例化的具體工廠類;
·一個(gè)具體工廠只能創(chuàng)建一種具體產(chǎn)品
8.示例
有一間工廠(僅生產(chǎn)A類產(chǎn)品)喉酌,隨著客戶需求的變化热凹,可戶需要生產(chǎn)B類產(chǎn)品泵喘。
·沖突:改變?cè)兴芰霞庸S的配置和變化非常困難,假設(shè)下一次客戶需要再發(fā)生變化般妙,再次改變將增大非常大的成本纪铺;
·解決方案:小成決定置辦塑料分廠B來生產(chǎn)B類產(chǎn)品;
代碼:
public class MethodFactory {
public static void main(String[] args) {
FactoryA factoryA=new FactoryA();
factoryA.manufacture().make();
FactoryB factoryB=new FactoryB();
factoryB.manufacture().make();
}
}
//1.創(chuàng)建抽象工廠類碟渺,定義具體工廠的公共接口鲜锚;
abstract class AbstractFactory{
public abstract Product manufacture();
}
//2.創(chuàng)建抽象產(chǎn)品類,定義具體產(chǎn)品的公共接口
abstract class Product{
public abstract void make();
}
//3.創(chuàng)建具體產(chǎn)品類(繼承抽象產(chǎn)品類或者實(shí)現(xiàn)接口)&定義生產(chǎn)的具體產(chǎn)品苫拍;
class ProductA extends Product{
//具體產(chǎn)品A類
@Override
public void make() {
System.out.println("生產(chǎn)了A類產(chǎn)品");
}
}
class ProductB extends Product{
//具體產(chǎn)品B類
@Override
public void make() {
System.out.println("生產(chǎn)了B類產(chǎn)品");
}
}
//4.創(chuàng)建具體工廠類(繼承抽象工廠類或者實(shí)現(xiàn)接口)芜繁,定義創(chuàng)建對(duì)應(yīng)具體產(chǎn)品實(shí)例的方法。
class FactoryA extends AbstractFactory{
//A工廠
@Override
public Product manufacture() {
return new ProductA();
}
}
class FactoryB extends AbstractFactory{
//B工廠
@Override
public Product manufacture() {
return new ProductB();
}
}
結(jié)果:
3.抽象工廠模式
1.基本介紹
1)抽象工廠模式:定義了一個(gè) interface 用于創(chuàng)建相關(guān)或有依賴關(guān)系的對(duì)象簇绒极,而無需指明具體的類
2)抽象工廠模式可以將簡(jiǎn)單工廠模式和工廠方法模式進(jìn)行整合骏令。
3)從設(shè)計(jì)層面看,抽象工廠模式就是對(duì)簡(jiǎn)單工廠模式的改進(jìn)(或者稱為進(jìn)一步的抽象)垄提。
4)將工廠抽象成兩層榔袋,AbsFactory(抽象工廠) 和 具體實(shí)現(xiàn)的工廠子類。程序員可以根據(jù)創(chuàng)建對(duì)象類型使用對(duì)應(yīng)的工廠子類铡俐。這樣將單個(gè)的簡(jiǎn)單工廠類變成了工廠簇凰兑,更利于代碼的維護(hù)和擴(kuò)展。
4)工廠方法模式中一個(gè)具體工廠只能創(chuàng)建一類產(chǎn)品审丘,而實(shí)際過程中吏够,一個(gè)工廠往往需要生產(chǎn)多類產(chǎn)品。為解決這類問題滩报,引入抽象工廠模式稿饰。
2.主要作用
允許使用抽象得接口來創(chuàng)建一組相關(guān)產(chǎn)品,而不需要知道或關(guān)心實(shí)際生產(chǎn)出得具體產(chǎn)品是什么露泊,這樣就可以從具體產(chǎn)品中被解耦。
3.解決得問題
工廠方法模式得缺點(diǎn)
4.模式的組成
抽象產(chǎn)品簇(AbastractProduct):描述抽象產(chǎn)品得公共接口旅择,抽象產(chǎn)品得父類
抽象產(chǎn)品(Product):描述產(chǎn)品的公共接口惭笑,是具體產(chǎn)品的父類。
具體產(chǎn)品(ConcreteProduct):描述生產(chǎn)的具體產(chǎn)品生真,抽象產(chǎn)品的子類沉噩,工廠類創(chuàng)建的目標(biāo)類,描述的具體產(chǎn)品柱蟀。
抽象工廠(Factory):描述具體工廠的公共接口川蒙,具體工廠的父類。
具體工廠(ConcreteCreator):實(shí)現(xiàn)FactoryMethod工廠方法創(chuàng)建產(chǎn)品的實(shí)例长已,抽象工廠的子類畜眨,被外界調(diào)用昼牛。
5.使用步驟
1.創(chuàng)建抽象工廠類,定義具體工廠的公共接口康聂;
2.創(chuàng)建抽象產(chǎn)品簇類贰健,定義抽象產(chǎn)品的公共接口;
3.創(chuàng)建抽象產(chǎn)品類(繼承抽象產(chǎn)品簇類或者實(shí)現(xiàn)接口)恬汁,定義具體產(chǎn)品的公共接口伶椿;
4.創(chuàng)建具體產(chǎn)品類(繼承抽象產(chǎn)品類或者實(shí)現(xiàn)接口),定義生產(chǎn)的具體產(chǎn)品。
5.創(chuàng)建具體工廠類(繼承抽象工廠類或者接口),定義創(chuàng)建對(duì)應(yīng)具體產(chǎn)品實(shí)例的方法氓侧。
6.客戶端通過實(shí)例化具體的工廠類脊另,并調(diào)用其創(chuàng)建不同目標(biāo)產(chǎn)品的方法創(chuàng)建不同具體產(chǎn)品類的實(shí)例。
6.優(yōu)點(diǎn)
降低耦合:抽象工廠模式將具體產(chǎn)品的創(chuàng)建延遲到具體工廠的子類中约巷,這樣將對(duì)象的創(chuàng)建封裝起來偎痛,可以減少客戶端與具體產(chǎn)品類之間的依賴,從而使系統(tǒng)耦合度降低载庭,這樣更有利于后期的維護(hù)和擴(kuò)展看彼。
跟符合開放閉合原則:新增一種產(chǎn)品類時(shí),只需要增加相應(yīng)的具體產(chǎn)品代碼和相應(yīng)的工廠子類即可囚聚。
符合單一職責(zé)原則:每個(gè)具體工廠類只負(fù)責(zé)創(chuàng)建對(duì)應(yīng)的產(chǎn)品
不使用靜態(tài)工廠方法靖榕,可以形成基于繼續(xù)的等級(jí)結(jié)構(gòu)。
7.缺點(diǎn)
抽象工廠模式很難支持新種類產(chǎn)品的變化顽铸。這是因?yàn)槌橄蠊S接口中已經(jīng)確定了可以被創(chuàng)建的產(chǎn)品集合茁计,如果需要添加新產(chǎn)品,此時(shí)必須去修改抽象工廠的接口谓松,這樣就涉及到抽象工廠類的以及所有子類的改變星压,這樣也就違背了開放封閉原則。
8.示例
·背景:小成有兩間塑料加工廠(A廠僅生產(chǎn)容器類產(chǎn)品鬼譬;B廠僅生產(chǎn)模具類產(chǎn)品)娜膘;隨著客戶需求的變化,A廠所在地的客戶需要也模具類產(chǎn)品优质,B廠所在地的客戶也需要容器類產(chǎn)品竣贪;
沖突:沒有資源(資金+租位)在當(dāng)?shù)胤謩e開設(shè)多一家注塑分廠
解決方案:在原有的兩家塑料廠里增設(shè)生產(chǎn)需求的功能,即A廠能生產(chǎn)容器+模具產(chǎn)品巩螃;B廠間能生產(chǎn)模具+容器產(chǎn)品演怎。
代碼:
public class AbstractFactory {
public static void main(String[] args) {
//A廠
FactoryA fA=new FactoryA();
fA.manufactureContainer().make();
fA.manufactureMould().make();
//B廠
FactoryB fB=new FactoryB();
fB.manufactureContainer().make();
fB.manufactureMould().make();
}
}
//1.創(chuàng)建抽象工廠類,定義具體工廠的公共接口避乏;
abstract class Factory{
public abstract AbstractProduct manufactureContainer();
public abstract AbstractProduct manufactureMould();
}
//2.創(chuàng)建抽象產(chǎn)品簇類爷耀,定義抽象產(chǎn)品的公共接口;
abstract class AbstractProduct{
public abstract void make();
}
//3.創(chuàng)建抽象產(chǎn)品類(繼承抽象產(chǎn)品簇類或者實(shí)現(xiàn)接口)拍皮,定義具體產(chǎn)品的公共接口歹叮;
abstract class ContainerProduct extends AbstractProduct{
//容器抽象類
public abstract void make();
}
abstract class MouldProduct extends AbstractProduct{
//模具抽象類
public abstract void make();
}
//4.創(chuàng)建具體產(chǎn)品類(繼承抽象產(chǎn)品類或者實(shí)現(xiàn)接口),定義生產(chǎn)的具體產(chǎn)品跑杭。
class ContainerProductA extends ContainerProduct{
//容器產(chǎn)品A類
@Override
public void make() {
System.out.println("生產(chǎn)出了容器產(chǎn)品A類");
}
}
class ContainerProductB extends ContainerProduct{
//容器產(chǎn)品B類
@Override
public void make() {
System.out.println("生產(chǎn)出了容器產(chǎn)品B類");
}
}
class MouldProductA extends MouldProduct{
//模具產(chǎn)品A類
@Override
public void make() {
System.out.println("生產(chǎn)出了模具產(chǎn)品A類");
}
}
class MouldProductB extends MouldProduct{
//模具產(chǎn)品B類
@Override
public void make() {
System.out.println("生產(chǎn)出了模具產(chǎn)品B類");
}
}
//5.創(chuàng)建具體工廠類(繼承抽象工廠類或者接口),定義創(chuàng)建對(duì)應(yīng)具體產(chǎn)品實(shí)例的方法。
class FactoryA extends Factory{
//工廠A盗胀,生產(chǎn)模具和容器
@Override
public AbstractProduct manufactureContainer() {
return new ContainerProductA();
}
@Override
public AbstractProduct manufactureMould() {
return new MouldProductA();
}
}
class FactoryB extends Factory{
//工廠B艘蹋,生產(chǎn)模具和容器
@Override
public AbstractProduct manufactureContainer() {
return new ContainerProductB();
}
@Override
public AbstractProduct manufactureMould() {
return new MouldProductB();
}
}
截圖:
emmmm 當(dāng)看到大佬的博客的時(shí)候,為了以后復(fù)習(xí)和加深記憶票灰,不知不覺又當(dāng)上了博客搬運(yùn)工女阀,如果想看原文參考下方鏈接。