1. 程式人生 > >Spring:工廠模式哪裡解耦了?

Spring:工廠模式哪裡解耦了?

菜瓜:我一定是太菜了,為什麼別人說Spring遮蔽了new關鍵字建立物件就很絲滑?我完全get不到這個操作的好處啊,我自己寫new它也很香啊

水稻:emmmm,換個角度想啊,如果把現在用的註解@Autowired@Resource給幹掉,你想在Controller裡面引用Service,你會怎麼做?new 一個?

菜瓜:對啊,我new一個怎麼了,不也可以用?

水稻:那如果,我另一個Controller裡面也要用同一個Service,是不是再new一個?有很多個這種Controller是不是new很多個Service?

菜瓜:這。。。我有另一個方法,把Service放在一個容器裡,Controller用的時候從容器裡面拿?

水稻:哇塞,Spring應該請你去寫他們的框架啊

菜瓜:Spring是這麼做的?

水稻:不知道你聽沒聽過簡單工廠這種設計模式,用於將物件的建立和使用隔離開來,達到解耦的目的。工廠負責建立物件,並且可以干預建立的邏輯

菜瓜:嗯,簡單工廠,工廠方法,抽象工廠我都略懂?

水稻:。。。。Talk is cheap , show me your code ! 就簡單工廠就行了

菜瓜:下面這樣的

package club.interview.design_pattern.chapt2_factory_pattern;

/**
 * @author QuCheng on 2020/6/13.
 */
public class SimpleFactory {

    abstract static class AbstractPhone {
        abstract void call();
    }

    static class XiaoMi extends AbstractPhone {
        @Override
        void call() {
            System.out.println("小米手機打電話。。。。");
        }
    }

    static class Meizu extends AbstractPhone {
        @Override
        void call() {
            System.out.println("魅族手機打電話。。。。");
        }
    }

    public AbstractPhone getPhone(String phoneType) {
        if ("小米".equals(phoneType)) {
            return new XiaoMi();
        } else if ("魅族".equals(phoneType)) {
            return new Meizu();
        }
        return null;
    }


    public static void main(String[] args) {
        SimpleFactory s = new SimpleFactory();
        s.getPhone("小米").call();
        s.getPhone("魅族").call();
    }

}

水稻:那你肯定知道,這種寫法的侷限性。依靠phoneType來建立物件不利於擴充套件。如果現在的需求生產的物件不限定返回型別,給啥就建立啥,怎麼做

菜瓜:動態建立物件?那不是反射嗎?是不是這樣

package club.interview.design_pattern.chapt2_factory_pattern;

/**
 * @author QuCheng on 2020/6/13.
 */
public class SpringFactory {

    static class XiaoMi {
        void call() {
            System.out.println("小米手機打電話。。。。");
        }
    }

    static class Meizu  {
        void call() {
            System.out.println("魅族手機打電話。。。。");
        }
    }

    static class HuaWei  {
        void call() {
            System.out.println("華為手機打電話。。。。");
        }
    }

    public <T> T getPhone(Class<T> clazz) {
        try {
            return clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) {
        SpringFactory s = new SpringFactory();
        s.getPhone(XiaoMi.class).call();
        s.getPhone(Meizu.class).call();
        s.getPhone(HuaWei.class).call();
    }

}

水稻:秀啊!!厲害厲害。相比你也知道,此時如果我想在建立過程中加入一點點自己的邏輯,那也是很絲滑的。

菜瓜:哦,原來是這樣。Spring利用工廠將物件的建立和使用進行隔離,還可以定製一些bean物件的建立邏輯。學到了,學到了。

水稻:我也學到了,反射和設計模式用的6啊。當然,Spring的工廠遠沒有你現在想的這麼簡單。你再仔細品品

 

總結:

  • Spring利用反射建立物件,並將建立好的物件放入一個大工廠,實現了物件建立和使用的解耦。後需要使用的時候可以方便的通過BeanFactory.getBean()獲取。在此之上還擴充套件了堆註解的支援,使用註解就可以注入物件。這就是傳說中的DI(Dependency Inject)依賴注入

&n