23種設計模式之——工廠設計模式

前言:記得大二時上過一門設計模式的課,當時聽的那叫一個懵逼。。如今工作半年了,想把東西再撿起來,順便記錄一下。。工廠模式是平時接觸的多一點的,就從工廠模式開始吧…

什麼是工廠設計模式?

工廠設計模式,顧名思義,就是用來生產對象的,是一種創建型設計模式。在面嚮對象語言中,萬物皆對象,這些對象都需要創建,如果創建的時候直接new該對象,就會對該對象耦合嚴重,假如我們要更換對象,所有new對象的地方都需要修改一遍,這顯然違背了軟件設計的開閉原則,如果我們使用工廠來生產對象,我們就只和工廠打交道就可以了,徹底和對象解耦,如果要更換對象,直接在工廠裏更換該對象即可,達到了與對象解耦的目的;所以說,工廠模式最大的優點就是:解耦

工廠模式又包含三種:

  • 簡單工廠
  • 工廠方法
  • 抽象工廠

簡單工廠設計模式

定義:一個工廠方法,生存某類的對象。

角色:

  1. 抽象產品
  2. 具體產品
  3. 具體工廠
  4. 產品使用者

工廠模式是用來創建某一類對象的工廠,因此需要首先抽象產品,比如蘋果,橘子都屬於水果,因此我們可以先抽象出一個水果類,再定義一個水果工廠,用來生產不同的水果

水果接口:

public interface Fruit{
    void eat();  // 定義一個水果被吃了的方法
}

具體類:蘋果或者橘子

public class Apple implement Fruit{
    @Override
    void eat(){
        System.out.print("蘋果被吃了");
    }
}
public class Orange implement Fruit{
    @Override
    void eat(){
        System.out.print("橘子被吃了");
    }
}

具體工廠:水果工廠類

public class FruitFactory{
    // 提供一個靜態方法給外部使用
    public static Fruit createFruit(String type){
        switch(type){
            case 'apple':
                return new Apple();
                break;
            case 'orange':
                return new Orange();
                break;
            // ... 還可以有很多
            default:
                System.out.print("暫不支持生產該類型");
        }
    }
}

產品使用:

Apple apple = (Apple)FruitFactory.createFruit("apple");
apple.eat();// 蘋果被吃了

以上就是簡單工廠模式,其思想就是將類的創建交個工廠,當需要某個類時,從工廠裏取。簡單工廠模式雖然簡單,但有其弊端,就是當我需要生產一種新的水果產品,需要修改工廠,這顯然違反了六大設計原則的開閉原則。

爲解決該問題我們介紹第二種工廠模式:

工廠方法設計模式

定義:將工廠提取成一個接口或抽象類,具體生產什麼產品由子類決定;

角色:

  1. 抽象產品
  2. 具體產品
  3. 抽象工廠
  4. 具體工廠

和簡單工廠類一樣,我們需要將產品抽象出來,還用水果類,這次我們將工廠也抽象出來,具體生產什麼由子類決定:

省略水果接口,蘋果類,橘子類。。。

工廠接口

public interface FruitFactory{
    Fruit createFruit();// 生產水果的方法
}

蘋果工廠

public AppleFactory implements FruitFactory{
    @Override
    Fruit createFruit(){
        return new Apple();
    }
}
// 橘子工廠
public OrangeFactory implements FruitFactory{
    @Override
    Fruit createFruit(){
        return new Orange();
    }
}

使用產品

AppleFactory af=new AppleFactory();
Apple apple = af.createFruit();

以上這種方式,雖然解耦了,也遵循了開閉原則,但是問題根本還是沒有解決啊,換湯沒換藥,如果我需要的產品很多的話,需要創建非常多的工廠,所以這種方式的缺點也很明顯;於是我們再來看最後一種工廠模式:

抽象工廠設計模式

定義:爲創建一組相關或者是相互依賴的對象提供的一個接口,而不需要指定它們的具體類。
角色:

  1. 抽象產品
  2. 具體產品
  3. 抽象工廠
  4. 具體工廠

抽象工廠和工廠方法的模式基本一樣,區別在於,工廠方法是生產一個具體的產品,而抽象工廠可以用來生產一組相同,有相對關係的產品;重點在於一組,一批,一系列;舉個例子,假如生產小米手機(一不小心就給小米打了個廣告~),小米手機有很多系列,小米note、紅米note等;假如小米note生產需要的配件有825的處理器,6英寸屏幕,而紅米只需要650的處理器和5寸的屏幕就可以了;用抽象工廠來實現:

cpu接口和實現類

public interface Cpu {
    void run();

    class Cpu650 implements Cpu {
        @Override
        public void run() {
            System.out.print("650cpu運行了"); 
        }
    }

    class Cpu825 implements Cpu {
        @Override
        public void run() {
            System.out.print("825cpu運行了"); 
        }
    }
}

屏幕接口和實現類

public interface Screen {

    void size();

    class Screen5 implements Screen {

        @Override
        public void size() {
            System.out.print("5寸的顯示屏");
        }
    }

    class Screen6 implements Screen {

        @Override
        public void size() {
           System.out.print("6寸的顯示屏");
        }
    }
}

工廠接口

public interface PhoneFactory {

    Cpu getCpu();//使用的cpu

    Screen getScreen();//使用的屏幕
}

具體工廠實現類:小米手機工廠類

public class XiaoMiFactory implements PhoneFactory {
    @Override
    public Cpu getCpu() {
        return new Cpu825();//高性能處理器
    }

    @Override
    public Screen getScreen() {
        return new Screen6();//6寸大屏
    }
}

具體工廠實現類:紅米手機工廠類

public class HongMiFactory implements PhoneFactory {

    @Override
    public Cpu getCpu() {
        return new Cpu650();//高效處理器
    }

    @Override
    public Screen getScreen() {
        return new Screen5();//小屏手機
    }
}

現在可以在兩種cpu和兩種屏幕任意組合,得到相應性能的手機,以上例子可以看出,抽象工廠可以解決一系列的產品生產的需求,對於大批量,多系列的產品,用抽象工廠可以更好的管理和擴展;

總結

1、對於簡單工廠和工廠方法來說,兩者的使用方式實際上是一樣的,如果對於產品的分類和名稱是確定的,數量是相對固定的,推薦使用簡單工廠模式;
2、抽象工廠用來解決相對複雜的問題,適用於一系列、大批量的對象生產;

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