面向面試學習,一起來玩工廠設計模式

1. 小聲嗶嗶

    工廠設計模式算是經常在項目中使用的設計模式,屬於創建型模式,可以理解爲創建對象的設計模式。

    應用場景:根據業務情況需創建不同類型的對象,且對象又存在相似的業務邏輯,此時需要將創建對象的責任交由工廠類,工廠類會基於輸入創建對象。(該場景是根據自己的理解)

    在查閱資料時看到有人講工廠設計模式分爲三類,簡單工廠,工廠方法,抽象工廠,結合開發經驗而言,簡單工廠和抽象工廠是我使用較多的模式,所以本文僅着墨於此。

    文中的代碼庫:https://gitee.com/Coline/JobWanted

    模塊位置:design模塊的com.coline.design.factory包中

2. 簡單工廠模式

    簡單工廠模式就是我們平時使用最多的模式,假設我們項目需要小米手機和華爲手機兩種手機,手機需要選擇CPU和屏幕型號,首先我們有一個手機類型的接口PhoneType (其實這裏涉及到了模板涉及模式,也是JDK中使用較多的設計模式)

package com.coline.design.factory.simplyway.intf;

/**
 * @author Coline
 * @Description 手機類型接口類
 */
public interface PhoneType {
    /**
     * CPU型號
     */
    void cpu();

    /**
     * 屏幕型號
     */
    void screen();
}

    新建小米手機類和華爲手機類並實現PhoneType ,如下:

package com.coline.design.factory.simplyway.imp;

import com.coline.design.factory.simplyway.intf.PhoneType;

/**
 * @author Coline
 * @Description 小米產品,繼承PhoneType接口
 */
public class XiaoMi implements PhoneType {
    @Override
    public void cpu() {
        System.out.println("XiaoMi Cpu: 650");
    }

    @Override
    public void screen() {
        System.out.println("XiaoMi Screen: 5.5");
    }
}
package com.coline.design.factory.simplyway.imp;

import com.coline.design.factory.simplyway.intf.PhoneType;

/**
 * @author Coline
 * @Description 華爲產品,繼承PhoneType接口
 */
public class HuaWei implements PhoneType {
    @Override
    public void cpu() {
        System.out.println("HuaWei CPU: 950");
    }

    @Override
    public void screen() {
        System.out.println("HuaWei Screen: 6.0");
    }
}

    如果不使用工廠設計模式,那麼我們會在項目中的各個位置到處new這兩個實現類,代碼會顯得不優雅,丟失了程序員的尊嚴。所以我們可以將新建對象的職責交由工廠類來完成,代碼如下:

package com.coline.design.factory.simplyway;

import com.coline.design.factory.simplyway.imp.HuaWei;
import com.coline.design.factory.simplyway.imp.XiaoMi;
import org.junit.Test;

/**
 * 簡單的工廠模式
 * 我的博客地址:https://blog.csdn.net/u011294519/article/details/104150400
 *
 * @author Coline
 * @ClassName PhoneFactoryTest
 * @Date 2020/2/1 23:45
 */
public class PhoneFactoryTest {
    private final static String XIAOMI = "XIAOMI";
    private final static String HUAWEI = "HUAWEI";

    Object createPhone(String brand) {
        if (XIAOMI.equals(brand)) {
            return new XiaoMi();
        } else if (HUAWEI.equals(brand)) {
            return new HuaWei();
        } else {
            throw new IllegalArgumentException("Param error");
        }
    }

    @Test
    public void testPhoneFactory() {
        XiaoMi xiaomi = (XiaoMi) createPhone(XIAOMI);
        xiaomi.cpu();
        xiaomi.screen();

        HuaWei huawei = (HuaWei) createPhone(HUAWEI);
        huawei.cpu();
        huawei.screen();
    }
}

    上面PhoneFactory類中的main方法僅做測試使用,僅供參考,測試結果如下:

3. 抽象工廠

    抽象工廠是爲了應對更加複雜的業務情況,業務更便於擴展,主要設計思想是以業務屬性爲維度,將代碼邏輯上移至業務屬性,方便批量處理。

    業務場景:假設還是小米手機和華爲手機的場景,手機廠商會根據戰略目標選擇不同的CPU和屏幕來滿足不同層級的需求,因此可以將CPU和屏幕理解爲與手機本身爲配件和整體的關係,所以首先我們有CPU的接口類,屏幕的接口類用於規範有哪些CPU和屏幕型號,代碼如下:

package com.coline.design.factory.abstractway.intf;

/**
 * @author Coline
 * @ClassName Cpu
 * @Date 2020/2/2 0:03
 * @Description Cpu工廠
 */
public interface Cpu {
    /**
     * CPU型號
     * @return: void
     **/
    void model();

    /**
     * @ClassName Cpu850
     * @Date 2020/2/2 0:31
     * @Description Cpu850
     */
    class Cpu850 implements Cpu {
        @Override
        public void model() {
            System.out.println("Use Cpu850");
        }
    }

    /**
     * @ClassName Cpu950
     * @Date 2020/2/2 0:32
     * @Description Cpu950
     */
    class Cpu950 implements Cpu {
        @Override
        public void model() {
            System.out.println("Use Cpu950");
        }
    }
}
package com.coline.design.factory.abstractway.intf;

/**
 * @author Coline
 * @ClassName Screen
 * @Date 2020/2/2 0:11
 * @Description 屏幕工廠
 */
public interface Screen {
    /**
     * 型號
     * @return: void
     **/
    void model();

    /**
     * @ClassName Screen5
     * @Date 2020/2/2 0:33
     * @Description Screen5
     */
    class Screen5 implements Screen {
        @Override
        public void model() {
            System.out.println("Use Screen 5");
        }
    }

    /**
     * @ClassName Screen6
     * @Date 2020/2/2 0:33
     * @Description Screen6
     */
    class Screen6 implements Screen {
        @Override
        public void model() {
            System.out.println("Use Screen 6");
        }
    }
}

    同時我們需要一個手機的工廠接口類用於規範手機的組成,代碼如下:

package com.coline.design.factory.abstractway.intf;

/**
 * @author Coline
 * @ClassName PhoneFactory
 * @Date 2020/2/2 0:27
 * @Description 手機工廠
 */
public interface PhoneFactory {
    /**
     * 手機需要什麼CPU
     * @return: void
     **/
    void getCpu();
    /**
     * 手機需要什麼屏幕
     * @return: void
     **/
    void getScreen();
}

    而後,我們根據業務需求,新建具體的手機類並實現手機工廠接口PhoneFactory 

package com.coline.design.factory.abstractway.imp;

import com.coline.design.factory.abstractway.intf.Cpu;
import com.coline.design.factory.abstractway.intf.PhoneFactory;
import com.coline.design.factory.abstractway.intf.Screen;

/**
 * @author Coline
 * @ClassName XiaoMi
 * @Date 2020/2/2 0:36
 * @Description 小米手機,CPU850,屏幕5寸
 */
public class XiaoMi implements PhoneFactory {
    @Override
    public void getCpu() {
        new Cpu.Cpu850().model();
    }

    @Override
    public void getScreen() {
        new Screen.Screen5().model();
    }
}
package com.coline.design.factory.abstractway.imp;

import com.coline.design.factory.abstractway.intf.Cpu;
import com.coline.design.factory.abstractway.intf.PhoneFactory;
import com.coline.design.factory.abstractway.intf.Screen;

/**
 * @author Coline
 * @ClassName HuaWei
 * @Date 2020/2/2 0:38
 * @Description 華爲手機CPU950,屏幕6寸
 */
public class HuaWei implements PhoneFactory{
    @Override
    public void getCpu() {
        new Cpu.Cpu950().model();
    }

    @Override
    public void getScreen() {
        new Screen.Screen6().model();
    }
}

    代碼邏輯就此完成,測試類如下:

package com.coline.design.factory.abstractway;

import com.coline.design.factory.abstractway.imp.HuaWei;
import com.coline.design.factory.abstractway.imp.XiaoMi;
import org.junit.Test;

/**
 * @author Coline
 * @ClassName CreatePhoneTest
 * @Date 2020/2/2 0:39
 * @Description 抽象工廠模式測試類
 * 我的博客地址:https://blog.csdn.net/u011294519/article/details/104150400
 */
public class CreatePhoneTest {

    @Test
    public void testCreatPhone() {
        System.out.println("----------------------------");
        System.out.println("Create XiaoMi");
        XiaoMi xiaomi = new XiaoMi();
        xiaomi.getCpu();
        xiaomi.getScreen();

        System.out.println("----------------------------");
        System.out.println("Create Huawei");
        HuaWei huawei = new HuaWei();
        huawei.getCpu();
        huawei.getScreen();
    }
}

    測試結果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章