工廠模式的主要作用:實現了創建者和調用者的分離。
工廠模式的核心本質:實例化對象,用工廠方法代替new操作;將選擇實現類、創建對象統一管理和控制。從而將調用者和我們的實現類進行解耦。
詳細可以分爲:
簡單工廠模式:用來生產同一等級結構中的任意產品。(對於增加新的產品,需要修改原來的代碼)
工廠方法模式:用來生產同一等級結構中的固定產品。(支持增加任意產品,不需要修改已有代碼)
抽象工廠模式:用來生產不同產品族的全部產品。(對於增加新的產品無能爲力,支持增加產品族)
面向對象設計的基本原則:
1 OCP 開閉原則(Open Closed Principle):一個軟件的實體應該對擴展開放,對修改關閉;
2 DIP 依賴倒轉原則(Dependence Inversion Principle):要針對接口編程,不要針對實現編程;
3 LoD 迪米特法則(Law of Demeter):只與你直接的朋友通信,避免和陌生人通信。
1、簡單工廠模式
1.1 創建接口
package com.zdw.factory.simpleFactory;
public interface Car {
void run();
}
1.2 創建兩個實現類
1.2.1 奧迪車
package com.zdw.factory.simpleFactory;
public class Audi implements Car {
@Override
public void run() {
System.out.println("我是一輛奧迪車,我百公里加速8秒");
}
}
1.2.2 吉利車
package com.zdw.factory.simpleFactory;
public class JiLi implements Car {
@Override
public void run() {
System.out.println("我是一輛吉利車,我百公里加速10秒");
}
}
1.3 創建工廠類
通過工廠類來創建不同的實現類對象:
package com.zdw.factory.simpleFactory;
/**
* 簡單工廠類,通過參數來創建不同的實現對象
*/
public class CarFactory {
public static Car createCar(String type){
if("奧迪".equals(type)){
return new Audi();
}else if("吉利".equals(type)){
return new JiLi();
}else {
return null;
}
}
}
1.4 測試
package com.zdw.factory.simpleFactory;
public class TestSimpleFactory {
public static void main(String[] args) {
Car audi = CarFactory.createCar("奧迪");
Car jiLi = CarFactory.createCar("吉利");
audi.run();
jiLi.run();
}
}
1.5 要點
1、簡單工廠模式也叫靜態工廠模式,因爲一般工廠類的方法都是靜態方法,通過類名直接調用;
2、對於增加新產品,就必須要修改已有代碼。
2、工廠方法模式
簡單工廠模式不能完全滿足OCP開閉原則,而工廠方法模式可以解決這個問題;
工廠方法模式和簡單工廠模式最大的不同在於:簡單工廠模式只有一個工廠類(對於一個小項目或一個模塊而言),而工廠方法模式有一組實現了相同接口的工廠類。
2.1 創建接口和實現類
我們創建的Car接口及其兩個實現類Audi和JiLi是跟上面的簡單工廠模式的是一樣的代碼,這裏不再贅述。
2.2 創建工廠接口和工廠實現
2.2.1 創建工廠接口
工廠接口中有一個方法,方法的作用是用來創建Car對象;
package com.zdw.factory.factoryMethod;
/**
* 工廠方法的接口
*/
public interface CarFactory {
Car createCar();
}
2.2.2 創建工廠實現類
奧迪車的工廠類
package com.zdw.factory.factoryMethod;
public class AudiFactory implements CarFactory {
@Override
public Car createCar() {
return new Audi();
}
}
吉利車的工廠類
package com.zdw.factory.factoryMethod;
public class JiLiFactory implements CarFactory {
@Override
public Car createCar() {
return new JiLi();
}
}
2.3 測試
package com.zdw.factory.factoryMethod;
public class TestFactoryMethod {
public static void main(String[] args) {
Car audi = new AudiFactory().createCar();
Car jiLi = new JiLiFactory().createCar();
audi.run();
jiLi.run();
}
}
現在如果我們需要新增一個產品奔馳車,那麼我們不需要修改之前的代碼,只要新增一個BenChi類實現Car接口,通過新增一個BenChiFactory實現CarFactory工廠接口。這樣就滿足了OCP開閉原則了。但是它會新增很多的類,會變得複雜,所以其實項目中簡單工廠模式是用的比較多的。
3、抽象工廠模式
抽象工廠模式用來生產不同產品族的全部產品。對於增加新的產品,無能爲力,但是支持新增新的產品族。
抽象工廠模式是工廠方法模式的升級版,在有多個業務品種,業務分類時,通過抽象工廠生產需要的對象是一種非常好的解決方式。
下面我們還是以Car作爲例子,假設Car是由三個主要的部件組成的:發動機,輪胎和座椅。不同等級的部件可以生產出不同的Car。
3.1 創建發動機及其實現
package com.zdw.factory.abstractFactory;
public interface Engine {
void run();
}
//高端發動機
class LuxuryEngine implements Engine{
@Override
public void run() {
System.out.println("高端發動機,轉速快,噪聲小");
}
}
//低端發動機
class LowEngine implements Engine{
@Override
public void run() {
System.out.println("低端發動機,轉速慢,噪聲好大好大。。。");
}
}
3.2 創建輪胎接口及其實現
package com.zdw.factory.abstractFactory;
public interface Tyre {
void revolve();
}
//高端輪胎
class LuxuryTyre implements Tyre{
@Override
public void revolve() {
System.out.println("高端輪胎,耐磨");
}
}
//低端輪胎
class LowTyre implements Tyre{
@Override
public void revolve() {
System.out.println("低端輪胎,不經磨,經常破。。。");
}
}
3.3 創建座椅接口及其實現
package com.zdw.factory.abstractFactory;
public interface Seat {
void massage();
}
class LuxurySeat implements Seat{
@Override
public void massage() {
System.out.println("高端座椅可以自動按摩的,很舒服");
}
}
class LowSeat implements Seat{
@Override
public void massage() {
System.out.println("低端座椅不能按摩,坐久了屁股痛。。。。");
}
}
3.4 創建生產Car的工廠接口及其實現
3.4.1 Car工廠接口
package com.zdw.factory.abstractFactory;
/**
* 生產車子的工廠接口
*/
public interface CarFactory {
Engine createEngine();
Tyre createTyre();
Seat createSeat();
}
3.4.2 高端車子的工廠類
package com.zdw.factory.abstractFactory;
public class LuxuryCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LuxuryEngine();//生產高端發動機
}
@Override
public Tyre createTyre() {
return new LuxuryTyre();//生產高端輪胎
}
@Override
public Seat createSeat() {
return new LuxurySeat();//生產高端座椅
}
}
3.4.3 低端車子的工廠類
package com.zdw.factory.abstractFactory;
public class LowCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LowEngine();//生產低端發動機
}
@Override
public Tyre createTyre() {
return new LowTyre();//生產低端輪胎
}
@Override
public Seat createSeat() {
return new LowSeat();//生產低端座椅
}
}
3.5 測試
package com.zdw.factory.abstractFactory;
public class TestAbstractFactory {
public static void main(String[] args) {
CarFactory carFactory = new LuxuryCarFactory();
Engine engine = carFactory.createEngine();
Tyre tyre = carFactory.createTyre();
Seat seat = carFactory.createSeat();
engine.run();
tyre.revolve();
seat.massage();
}
}
這樣我們通過不能的工廠實現類,就能創建不同的車子了。
3.6 抽象工廠的應用場景
JDK中的Calendar的getInstance方法;
JDBC中的Connection對象的獲取;
Hibernate中的SessionFactory創建Session;
Spring的IoC容器創建的管理的Bean對象;
反射Class對象的newInstance方法。