最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java超詳細(xì)講解設(shè)計(jì)模式之一的工廠模式

 更新時(shí)間:2022年03月26日 16:20:02   作者:〖雪月清〗  
工廠模式有 3 種不同的實(shí)現(xiàn)方式,分別是簡(jiǎn)單工廠模式、工廠方法模式和抽象工廠模式,工廠模式最大的特點(diǎn)就是解耦合,本篇帶你詳細(xì)了解它

工廠模式

在Java應(yīng)用程序中對(duì)象無(wú)處不在,這些對(duì)象都需要進(jìn)行創(chuàng)建,如果創(chuàng)建的時(shí)候直接new對(duì)象,那么如果我們要更換對(duì)象,所有new對(duì)象的地方都需要進(jìn)行更改。違背了軟件設(shè)計(jì)原則中的開閉原則。如果我們使用工廠生產(chǎn)對(duì)象,只需要在工廠中關(guān)注對(duì)象的改變即可,達(dá)到了與對(duì)象解耦的目的,工廠模式最大的特點(diǎn)就是解耦合

補(bǔ)充:

開閉原則: 對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。在程序需要進(jìn)行擴(kuò)展的時(shí)候,不能去修改原有的代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果。是為了使程序的擴(kuò)展性好,易于維護(hù)和升級(jí)。

1.簡(jiǎn)單工廠

1.1結(jié)構(gòu)

  • 抽象產(chǎn)品: 定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能。
  • 具體產(chǎn)品: 實(shí)現(xiàn)或者繼承抽象產(chǎn)品的子類
  • 具體工廠: 提供了創(chuàng)建產(chǎn)品的方法,調(diào)用者通過(guò)該方法來(lái)創(chuàng)建產(chǎn)品。

1.2實(shí)現(xiàn)

以點(diǎn)咖啡為例:

咖啡抽象類

public abstract class Coffee {
    /**
     * 獲取咖啡類型
     * @return
     */
    public abstract  String getName();

    /**
     *加糖
     */
    public  void addSugar(){
        System.out.println("加糖");
    }
    /**
     *加奶
     */
    public void addMilk(){
        System.out.println("加奶");
    }
}

美式咖啡類

public class AmericanCoffee  extends Coffee{

@Override
    public String getName(){
        return "美式咖啡";
    }
}

拿鐵咖啡類

public class LatteCoffee extends Coffee {

    @Override
    public String getName(){
        return "拿鐵咖啡";
    }
}

咖啡工廠類

public class CoffeeFactory {

    public Coffee createCoffee(String type){
      Coffee coffee = null;
      if("american".equals(type)){
          coffee = new AmericanCoffee();
      }else if("latten".equals(type)){
          coffee = new LatteCoffee();
      }else{
          throw new RuntimeException("沒有此類型的咖啡");
      }
      return coffee;
    }
}

咖啡店類

public class CoffeeStore {

    public Coffee orderCoffee(String type){
        CoffeeFactory factory = new CoffeeFactory();

      //調(diào)用生產(chǎn)咖啡的方法
        Coffee coffee = factory.createCoffee(type);
        coffee.addMilk();
        coffee.addSugar();

        return  coffee;
    }
}

測(cè)試類

public class Test {
    public static void main(String[] args) {
        CoffeeStore coffeeStore = new CoffeeStore();
        Coffee coffee = coffeeStore.orderCoffee("latten");
        System.out.println(coffee.getName());
    }
}

類圖

image-20220324100400375

咖啡工廠負(fù)責(zé)生產(chǎn)咖啡(具體工廠),咖啡店通過(guò)咖啡工廠選取咖啡

其實(shí)簡(jiǎn)單工廠是大家在實(shí)際寫代碼的時(shí)候經(jīng)常用到的,雖然簡(jiǎn)單工廠實(shí)現(xiàn)了咖啡店與咖啡的耦合,但是可以明顯看到咖啡與咖啡工廠又耦合起來(lái)了,后期如果增加咖啡的新品種,我們需要修改咖啡工廠的代碼,這又違背了“開閉原則”。

注意:

簡(jiǎn)單工廠和不使用工廠是有很大區(qū)別的,如果咖啡店有多個(gè),不使用工廠如果遇到新增咖啡需要修改所有咖啡店,但是使用工廠只需要修改咖啡工廠,類似于將所有咖啡店抽取出一個(gè)抽象的咖啡店。

1.3優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

封裝了創(chuàng)建對(duì)象的過(guò)程,可以通過(guò)參數(shù)直接獲取對(duì)象,把對(duì)象的創(chuàng)建和業(yè)務(wù)邏輯層分開,這樣可以避免之后修改客戶代碼,如果需要實(shí)現(xiàn)新產(chǎn)品直接修改工廠類,更容易擴(kuò)展。

缺點(diǎn):

增加新產(chǎn)品時(shí)還需要修改工廠類的代碼,違背了“開閉原則”。

1.4擴(kuò)展

靜態(tài)工廠,將工廠類中創(chuàng)建對(duì)象的功能定義為靜態(tài)的,這樣不需要再創(chuàng)建工廠類,直接通過(guò)類名調(diào)用靜態(tài)方法,類似于工具類

public class CoffeeFactory {
  //靜態(tài)方法
    public static Coffee createCoffee(String type){
      Coffee coffee = null;
      if("american".equals(type)){
          coffee = new AmericanCoffee();
      }else if("latten".equals(type)){
          coffee = new LatteCoffee();
      }else{
          throw new RuntimeException("沒有此類型的咖啡");
      }
      return coffee;
    }
}

2.工廠方法

對(duì)工廠進(jìn)行抽象,每一種產(chǎn)品對(duì)應(yīng)一個(gè)具體工廠,新增產(chǎn)品只需要再新增對(duì)應(yīng)的具體工廠,符合”開閉原則“

2.1結(jié)構(gòu)

  • 抽象工廠: 提供創(chuàng)建產(chǎn)品的接口,調(diào)用者通過(guò)它訪問(wèn)具體工廠的工廠方法來(lái)創(chuàng)建產(chǎn)品
  • 具體工廠: 主要是實(shí)現(xiàn)抽象工廠中的抽象方法,完成具體產(chǎn)品的創(chuàng)建
  • 抽象產(chǎn)品: 定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能
  • 具體產(chǎn)品: 實(shí)現(xiàn)抽象產(chǎn)品所定義的接口,由具體工廠來(lái)創(chuàng)建,與具體工廠之間一一對(duì)應(yīng)

2.2實(shí)現(xiàn)

抽象咖啡類和具體咖啡類不變

咖啡工廠(抽象工廠)

public interface CoffeeFactory {
    /**
     * 創(chuàng)建咖啡
     * @return
     */
    Coffee createCoffee();
}

美式咖啡工廠(具體工廠)

public class AmericanCoffeeFactory implements CoffeeFactory{
    //美式咖啡工廠對(duì)象,專門生產(chǎn)美式咖啡
    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }
}

拿鐵咖啡工廠(具體工廠)

public class LatteCoffeeFactory implements CoffeeFactory{
    //拿鐵咖啡工廠對(duì)象,專門生產(chǎn)拿鐵咖啡
    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }
}

咖啡店

public class CoffeeStore {

    private CoffeeFactory factory;

    public void setFactory(CoffeeFactory factory) {
        this.factory = factory;
    }

    /**
     * 點(diǎn)咖啡
     */
    public Coffee orderCoffee() {
        Coffee coffee = factory.createCoffee();
        coffee.addSugar();
        coffee.addMilk();
        return coffee;
    }
}

測(cè)試類

public class Test {
    public static void main(String[] args) {
        //創(chuàng)建咖啡店對(duì)象
        CoffeeStore coffeeStore = new CoffeeStore();
        //創(chuàng)建工廠對(duì)象
        CoffeeFactory factory = new AmericanCoffeeFactory();
        coffeeStore.setFactory(factory);

        //點(diǎn)咖啡
        Coffee coffee = coffeeStore.orderCoffee();

        System.out.println(coffee.getName());
    }
}

類圖

image-20220324105512679

我們只需要知道所點(diǎn)咖啡具體對(duì)應(yīng)的工廠對(duì)象,通過(guò)咖啡店調(diào)用對(duì)應(yīng)的工廠,由工廠創(chuàng)建咖啡對(duì)象實(shí)現(xiàn)點(diǎn)咖啡的過(guò)程

2.3優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 用戶只需要知道具體工廠就可以獲得所需產(chǎn)品,無(wú)需知道產(chǎn)品的具體創(chuàng)建過(guò)程
  • 在系統(tǒng)新增產(chǎn)品時(shí)只需要添加具體產(chǎn)品類和對(duì)應(yīng)的具體工廠類,無(wú)需對(duì)原工廠進(jìn)行修改符合“開閉原則”

缺點(diǎn):

每增加一個(gè)產(chǎn)品就要增加一個(gè)對(duì)應(yīng)的具體工廠類,增加的系統(tǒng)的復(fù)雜性。如果具體產(chǎn)品種類過(guò)多,那么大量的工廠類不僅難以管理,而且也會(huì)造成程序中創(chuàng)建的對(duì)象過(guò)多,嚴(yán)重影響內(nèi)存性能

3.抽象工廠

3.1結(jié)構(gòu)

  • 抽象工廠: 提供創(chuàng)建產(chǎn)品的接口,包含多個(gè)創(chuàng)建產(chǎn)品的方法,可以創(chuàng)建多個(gè)不同等級(jí)的產(chǎn)品
  • 具體工廠: 主要是實(shí)現(xiàn)抽象工廠中的多個(gè)抽象方法,完成具體產(chǎn)品的創(chuàng)建
  • 抽象產(chǎn)品: 定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能,抽象工廠模式有多個(gè)抽象產(chǎn)品
  • 具體產(chǎn)品: 實(shí)現(xiàn)抽象產(chǎn)品所定義的接口,由具體工廠來(lái)創(chuàng)建,與具體工廠是多對(duì)一關(guān)系

3.2實(shí)現(xiàn)

咖啡抽象類

public abstract class Coffee {
    /**
     * 獲取咖啡類型
     * @return
     */
    public abstract  String getName();

    /**
     *加糖
     */
    public  void addSugar(){
        System.out.println("加糖");
    }
    /**
     *加奶
     */
    public void addMilk(){
        System.out.println("加奶");
    }
}

美式咖啡類

public class AmericanCoffee  extends Coffee{

@Override
    public String getName(){
        return "美式咖啡";
    }
}

拿鐵咖啡類

public class LatteCoffee extends Coffee {

    @Override
    public String getName(){
        return "拿鐵咖啡";
    }
}

甜品抽象類

public abstract class Dessert {
 //甜品抽象類

    public abstract void show();
}

抹茶慕斯類

public class MatchaMousse extends Dessert{

//抹茶慕斯類
    @Override
    public void show() {
        System.out.println("抹茶慕斯");
    }


}

提拉米蘇類

public class Tiramisu  extends Dessert{
 //提拉米蘇類
    @Override
    public void show() {
        System.out.println("提拉米蘇");
    }
}

甜品工廠

public  interface DessertFactory {

    /**
     * 生產(chǎn)咖啡
     * @return
     */
    Coffee createCoffee();

    /**
     * 生產(chǎn)甜品
     * @return
     */
    Dessert createDessert();

}

美式風(fēng)味甜品工廠類

public class AmericanDessertFactory  implements DessertFactory{
    /**
     *美式風(fēng)味甜品工廠
     * 可以生產(chǎn)美式咖啡和抹茶慕斯
     */
    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new MatchaMousse();
    }
}

意大利風(fēng)味甜品工廠類

public class ItalyDessertFactory implements DessertFactory {

    /**
     *意大利風(fēng)味甜品工廠
     * 可以生產(chǎn)拿鐵咖啡和提拉米蘇
     */
    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new Tiramisu();
    }
}

測(cè)試類

public class Test {
    public static void main(String[] args) {
        //ItalyDessertFactory factory = new ItalyDessertFactory();
           AmericanDessertFactory factory = new AmericanDessertFactory();
 
          Coffee coffee = factory.createCoffee()
        Dessert dessert = factory.createDessert();

        System.out.println(coffee.getName());

        dessert.show();

    }
}

類圖

image-20220324150744271

由類圖可見,抽象工廠不再是一個(gè)具體工廠對(duì)應(yīng)一個(gè)產(chǎn)品,而是一個(gè)具體工廠對(duì)應(yīng)一個(gè)產(chǎn)品族。如果需要增加一個(gè)產(chǎn)品族只需加對(duì)應(yīng)的工廠類,符合”開閉原則“

3.3優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

在工廠方法的基礎(chǔ)上減少了部分對(duì)象的創(chuàng)建,適合于每次只使用同一產(chǎn)品族的對(duì)象這類應(yīng)用場(chǎng)景

缺點(diǎn):

當(dāng)產(chǎn)品族中需要增加一個(gè)產(chǎn)品時(shí),所有工廠都要修改

4.模式擴(kuò)展

配置文件+簡(jiǎn)單工廠

通過(guò)工廠模式+配置文件的方式解除工廠對(duì)象和產(chǎn)品對(duì)象的耦合。在工廠類中加載配置文件的全類名,通過(guò)反射創(chuàng)建對(duì)象并存儲(chǔ)在容器中,如果需要直接從容器中獲?。⊿pring IOC原理)

4.1實(shí)現(xiàn)

1.定義配置文件

american = com.xue.config_factory.AmericanCoffee
latten = com.xue.config_factory.LatteCoffee

2.改進(jìn)工廠類

public class CoffeeFactory {

    /**
     * 加載配置文件,獲取配置文件中配置的全類名,并創(chuàng)建該類的對(duì)象進(jìn)行存儲(chǔ)
     */

    //1.定義容器對(duì)象存儲(chǔ)咖啡對(duì)象
    private static HashMap<String, Coffee> map = new HashMap<>();


    //2.加載配置文件
    static {
        //創(chuàng)建 Properties對(duì)象
        Properties properties = new Properties();
        //調(diào)用properties對(duì)象中的load方法進(jìn)行配置文件的加載
        InputStream is = CoffeeFactory.class.getClassLoader().getResourceAsStream("bean.properties");
        try {
            properties.load(is);
            //從properties中獲取全類名
            Set<Object> keys = properties.keySet();

            for (Object key : keys) {
                String className = properties.getProperty((String) key);
                //通過(guò)反射創(chuàng)建對(duì)象
                Class class1 = Class.forName(className);
                Coffee coffee = (Coffee) class1.newInstance();

                //將名稱和對(duì)象存儲(chǔ)在容器中
                map.put((String) key,coffee);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //根據(jù)名稱獲取對(duì)象
    public static Coffee createCoffee(String name) {


        return map.get(name);
    }
}

靜態(tài)成員變量用來(lái)存儲(chǔ)創(chuàng)建的對(duì)象(鍵存儲(chǔ)的是名稱,值存儲(chǔ)的是對(duì)應(yīng)的對(duì)象),而讀取配置文件和創(chuàng)建對(duì)象寫在靜態(tài)代碼塊中只需要執(zhí)行一次

測(cè)試類

public class Test {
    public static void main(String[] args) {
        Coffee coffee = CoffeeFactory.createCoffee("american");
        System.out.println(coffee.getName());

        System.out.println("------------");

        Coffee latten = CoffeeFactory.createCoffee("latten");
        System.out.println(latten.getName());

    }

}

成功?。。?/p>

image-20220324165336860

以上就是Java設(shè)計(jì)模式——工廠模式的介紹及四種實(shí)現(xiàn)方式 往期鏈接:單例模式

到此這篇關(guān)于Java超詳細(xì)講解設(shè)計(jì)模式之一的工廠模式的文章就介紹到這了,更多相關(guān)Java 工廠模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring spel表達(dá)式使用方法示例

    Spring spel表達(dá)式使用方法示例

    這篇文章主要介紹了Spring spel表達(dá)式使用方法示例,通過(guò)一些實(shí)例向大家展示了spel表達(dá)式的用法,需要的朋友可以了解下。
    2017-09-09
  • 解決引用slf4j中Logger.info只打印出文字沒有數(shù)據(jù)的問(wèn)題

    解決引用slf4j中Logger.info只打印出文字沒有數(shù)據(jù)的問(wèn)題

    這篇文章主要介紹了解決引用slf4j中Logger.info只打印出文字沒有數(shù)據(jù)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Spring IoC容器常見獲取Bean的方式匯總示例解析

    Spring IoC容器常見獲取Bean的方式匯總示例解析

    這篇文章主要為大家介紹了Spring IoC容器常見獲取Bean的方式匯總示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • mybatis的insert插入后獲取自增id的方法詳解(從controller到mapper)

    mybatis的insert插入后獲取自增id的方法詳解(從controller到mapper)

    這篇文章主要介紹了mybatis的insert插入后獲取自增id的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-10-10
  • SpringBoot整合quartz實(shí)現(xiàn)定時(shí)任務(wù)

    SpringBoot整合quartz實(shí)現(xiàn)定時(shí)任務(wù)

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何整合quartz實(shí)現(xiàn)定時(shí)任務(wù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-10-10
  • Mybatis-Plus根據(jù)時(shí)間段去查詢數(shù)據(jù)的實(shí)現(xiàn)示例

    Mybatis-Plus根據(jù)時(shí)間段去查詢數(shù)據(jù)的實(shí)現(xiàn)示例

    這篇文章主要介紹了Mybatis-Plus根據(jù)時(shí)間段去查詢數(shù)據(jù)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java螺旋矩陣處理方法詳解

    Java螺旋矩陣處理方法詳解

    螺旋矩陣是指一個(gè)呈螺旋狀的矩陣,它的數(shù)字由第一行開始到右邊不斷變大,向下變大,向左變大,向上變大,如此循環(huán)。利用java實(shí)現(xiàn)的螺旋矩陣,當(dāng)輸入N之后,會(huì)自動(dòng)打印出螺旋矩陣
    2022-09-09
  • idea指定啟動(dòng)參數(shù)、環(huán)境變量的過(guò)程

    idea指定啟動(dòng)參數(shù)、環(huán)境變量的過(guò)程

    這篇文章主要介紹了idea指定啟動(dòng)參數(shù)、環(huán)境變量的操作過(guò)程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • java連接zookeeper實(shí)現(xiàn)zookeeper教程

    java連接zookeeper實(shí)現(xiàn)zookeeper教程

    這篇文章主要介紹了java連接zookeeper實(shí)現(xiàn)zookeeper教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • mybatis-plus常用注解@TableId和@TableField的用法

    mybatis-plus常用注解@TableId和@TableField的用法

    本文主要介紹了mybatis-plus常用注解@TableId和@TableField的用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評(píng)論

云南省| 喜德县| 仪征市| 涿鹿县| 汉阴县| 南召县| 双辽市| 东平县| 莎车县| 宜丰县| 瓦房店市| 灵宝市| 鹤庆县| 共和县| 阿坝| 溧阳市| 横峰县| 资溪县| 河津市| 马鞍山市| 渝北区| 江口县| 莎车县| 班戈县| 布拖县| 安宁市| 建阳市| 寿光市| 长白| 寿阳县| 徐闻县| 苍溪县| 封丘县| 绥棱县| 陵水| 郴州市| 勐海县| 沂南县| 孝义市| 清原| 鹤庆县|