1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      如何在Java中利用IOC控制反轉(zhuǎn)-創(chuàng)新互聯(lián)

      這篇文章給大家介紹如何在Java中利用IOC控制反轉(zhuǎn),內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

      創(chuàng)新互聯(lián)主要從事網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)石棉,十載網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220Java的特點(diǎn)有哪些

      Java的特點(diǎn)有哪些 1.Java語言作為靜態(tài)面向?qū)ο缶幊陶Z言的代表,實(shí)現(xiàn)了面向?qū)ο罄碚?,允許程序員以優(yōu)雅的思維方式進(jìn)行復(fù)雜的編程。 2.Java具有簡單性、面向?qū)ο?、分布式、安全性、平臺(tái)獨(dú)立與可移植性、動(dòng)態(tài)性等特點(diǎn)。 3.使用Java可以編寫桌面應(yīng)用程序、Web應(yīng)用程序、分布式系統(tǒng)和嵌入式系統(tǒng)應(yīng)用程序等。

      IOC范式揭秘

      控制反轉(zhuǎn)是一種帶有某些特征的模式。下面,給出了由Martin Fowler給出的一個(gè)IOC經(jīng)典范例,該范例實(shí)現(xiàn)的功能是從控制臺(tái)中收集用戶數(shù)據(jù)。

      public static void main(String[] args) {
        while (true) {
          BufferedReader userInputReader = new BufferedReader(
              new InputStreamReader(System.in));
          System.out.println("Please enter some text: ");
          try {
            System.out.println(userInputReader.readLine());
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }

      這個(gè)用例中,在main方法中進(jìn)行流程控制:在無限循環(huán)調(diào)用中,讀取用戶輸入,并將讀取的內(nèi)容輸出到控制臺(tái)上。完全又main方法控制何時(shí)去讀取用戶輸入,何時(shí)去輸出。

      考慮下,上述程序的一個(gè)新版本,該版本中需要通過圖形界面中的文本框來收件用戶輸入,另外還有個(gè)按鈕,該按鈕上綁定有一個(gè)action監(jiān)聽器。這樣的話,用戶每次點(diǎn)擊按鈕,輸入的文本由監(jiān)聽器收集并打印到面板。

      在這個(gè)版本的程序中,它實(shí)際上是由事件監(jiān)聽器模型(在這種情況下,這是框架)的控制下,調(diào)用開發(fā)者編寫的用于讀取和打印用戶輸入的代碼。簡單地說,框架將調(diào)用開發(fā)人員的代碼,而不是其他方式。該框架實(shí)際上是一個(gè)可擴(kuò)展的結(jié)構(gòu),它為開發(fā)人員提供了一組注入自定義代碼段的切入點(diǎn)。

      這種情況下,控制已經(jīng)被有效的反轉(zhuǎn)了。

      從更通用的角度來看,由框架定義的每個(gè)可調(diào)用擴(kuò)展點(diǎn)(以接口實(shí)現(xiàn),實(shí)現(xiàn)繼承(也稱為子類)的形式)是IoC的一種明確定義的形式。

      看下,下述這個(gè)簡單的Servlet例子:

      public class MyServlet extends HttpServlet {
       
        protected void doPost(
            HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
          // developer implementation here
        }
       
        protected void doGet(
            HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
          // developer implementation here
        }
       
      }

      此處,HttpServlet類(屬于框架)是完全控制程序的元素,而不是MyServlet這個(gè)子類。在由servlet容器創(chuàng)建之后,當(dāng)收到servlet的GET和POST的HTTP請(qǐng)求,doGet()和doPost()方法中的代碼會(huì)分別自動(dòng)調(diào)用。

      與典型的繼承方式相比,即子類是控制的元素,而不是基類,該例中,控件已經(jīng)被反轉(zhuǎn)了。

      事實(shí)上,servlet的方法是模板方法模式的實(shí)現(xiàn),稍后我們?cè)偕钊胗懻摗?/p>

      使用那些通過提供可擴(kuò)展API,秉承開閉原則的框架時(shí),使用框架的開發(fā)人員的角色,最終被歸結(jié)為定義自己的一組自定義類,即開發(fā)人員要么通過實(shí)現(xiàn)框架提供的一個(gè)或多個(gè)接口方式,要么通過繼承現(xiàn)有基類的方式。反過來,類的實(shí)例卻是直接框架進(jìn)行實(shí)例化,并且這些事例是被框架調(diào)用的。

      此處引用Fowler的話:該框架調(diào)用開發(fā)人員,而不是開發(fā)人員調(diào)用該框架。因此,IoC通常被稱為好萊塢原則:不要打電話給我們,我們會(huì)打電話給你。

      IOC的實(shí)現(xiàn)方式

      該問題上,顯而易見的是,實(shí)現(xiàn)控制反轉(zhuǎn)是有幾種不同方法的。我們不妨來總結(jié)一下,那些常見的實(shí)現(xiàn)方式。

      注入依賴實(shí)現(xiàn)IOC
      如前所述,注入依賴是IOC的一種實(shí)現(xiàn)方式,而且是最常見的一種面向?qū)ο笤O(shè)計(jì)方式。但是,思考一下:注入依賴究竟是如何達(dá)到控制反轉(zhuǎn)效果的呢?

      為了回答這個(gè)問題,我們給出如下一個(gè)原始的例子:

      public interface UserQueue { 
        void add(User user); 
        void remove(User user);
        User get();
       
      }
       
      public abstract class AbstractUserQueue implements UserQueue {
        protected LinkedList queue = new LinkedList<>();
       
        @Override
        public void add(User user) {
          queue.addFirst(user);
        }
       
        @Override
        public void remove(User user) {
          queue.remove(user);
        }
       
        @Override
        public abstract User get();
       
      }
       
      public class UserFifoQueue extends AbstractUserQueue { 
        public User get() {
          return queue.getLast();
        }
       
      }
       
      public class UserLifoQueue extends AbstractUserQueue {
        public User get() {
          return queue.getFirst();
        }
       
      }

      UserQueue 接口定義了公共的API,用于在一個(gè)隊(duì)列中去存放User對(duì)象(為了簡單明了,此處忽略User的具體實(shí)現(xiàn))。AbstractUserQueue則是為后續(xù)的繼承類,提供了一些公用的方法實(shí)現(xiàn)。最后的UserFifoQueue 和 UserLifoQueue,則是分別實(shí)現(xiàn)了FIFO 和 LIFO 隊(duì)列。

      這是,實(shí)現(xiàn)子類多態(tài)性的一種有效方式。但是這具體用什么來買我們好處呢?實(shí)際上,好處還是蠻多的。

      通過創(chuàng)建一個(gè)依賴于UserQueue抽象類型(也稱為DI術(shù)語中的服務(wù))的客戶端類,可以在運(yùn)行時(shí)注入不同的實(shí)現(xiàn),無需會(huì)重構(gòu)使用客戶端類的代碼:

      public class UserProcessor { 
        private UserQueue userQueue;
       
        public UserProcessor(UserQueue userQueue) {
          this.userQueue = userQueue;
        }
       
        public void process() {
          // process queued users here
        }
       
      }

      UserProcessor展示了,注入依賴確實(shí)是IOC的一種方式。

      我們可以通過一些硬編碼方式 如 new 操作,直接在構(gòu)造函數(shù)中實(shí)例化在UserProcessor中獲取對(duì)隊(duì)列的依賴關(guān)系。但是,這是典型的代碼硬編程,它引入了客戶端類與其依賴關(guān)系之間的強(qiáng)耦合,并大大降低了可測(cè)性。耳邊警鐘聲聲想起啦!不是嗎?是的,這樣設(shè)計(jì)真的很挫。

      該類在構(gòu)造函數(shù)中聲明對(duì)抽象類 UserQueue 的依賴。也就是說,依賴關(guān)系不再通過 在構(gòu)造函數(shù)中使用 new 操作, 相反,通過外部注入的方式,要么使用依賴注入框架(如CDI和谷歌的Guice),要么使用factory或builders模式。

      簡而言之,使用DI,客戶端類的依賴關(guān)系的控制,不再位于這些類中;而是在注入器中進(jìn)行:

      public static void main(String[] args) {
         UserFifoQueue fifoQueue = new UserFifoQueue();
         fifoQueue.add(new User("user1"));
         fifoQueue.add(new User("user2"));
         fifoQueue.add(new User("user3"));
         UserProcessor userProcessor = new UserProcessor(fifoQueue);
         userProcessor.process();
      }

      上述方式達(dá)到了預(yù)期效果,而且對(duì)UserLifoQueue的注入也簡單明了。顯而易見,DI確實(shí)是實(shí)現(xiàn)IOC的一種方式(該例中,DI是實(shí)現(xiàn)IOC的一個(gè)中間層)。

      觀察者模式實(shí)現(xiàn)IOC

      直接通過觀察者模式實(shí)現(xiàn)IOC,也是一種常見的直觀方式。廣義上講,通過觀察者實(shí)現(xiàn)IOC,與前文提到的通過GUI界面中的action監(jiān)聽器方式類似。但是在使用action監(jiān)聽器情況下,只有在特定的用戶事件發(fā)生時(shí)(點(diǎn)擊鼠標(biāo),鍵盤或窗口事件等),才會(huì)發(fā)生調(diào)用。觀察者模式通常用于在模型視圖的上下文中,跟蹤模型對(duì)象的狀態(tài)的變遷。

      在一個(gè)典型的實(shí)現(xiàn)中,一到多個(gè)觀察者綁定到可觀察對(duì)象(也稱為模式術(shù)語中的主題),例如通過調(diào)用addObserver方法進(jìn)行綁定。一旦定義了被觀察者和觀察者之間的綁定,則被觀察者狀態(tài)的變遷都會(huì)觸發(fā)調(diào)用觀察者的操作。

      為了深入了解這個(gè)概念,給出如下例子:

      @FunctionalInterface
      public interface SubjectObserver {
       
        void update();
       
      }

      值發(fā)生改變時(shí),會(huì)觸發(fā)調(diào)用上述這個(gè)很簡單的觀察者。真實(shí)情況下,通常會(huì)提供功能更豐富的API,如需要保存變化的實(shí)例,或者新舊值,但是這些都不需要觀察action(行為)模式,所以這里舉例盡量簡單。

      下面,給出一個(gè)被觀察者類:

      public class User {
       
        private String name;
        private List observers = new ArrayList<>();
       
        public User(String name) {
          this.name = name;
        }
       
        public void setName(String name) {
          this.name = name;
          notifyObservers();
        }
       
        public String getName() {
          return name;
        }
       
        public void addObserver(SubjectObserver observer) {
          observers.add(observer);
        }
       
        public void deleteObserver(SubjectObserver observer) {
          observers.remove(observer);
        }
       
        private void notifyObservers(){
          observers.stream().forEach(observer -> observer.update());
        }
      }

      User類中,當(dāng)通過setter方法變更其狀態(tài)事,都會(huì)觸發(fā)調(diào)用綁定到它的觀察者。

      使用主題觀察者和主題,以下是實(shí)例給出了觀察方式:

      public static void main(String[] args) {
        User user = new User("John");
        user.addObserver(() -> System.out.println(
            "Observable subject " + user + " has changed its state."));
        user.setName("Jack");
      }

      每當(dāng)User對(duì)象的狀態(tài)通過setter方法進(jìn)行修改時(shí),觀察者將被通知并向控制臺(tái)打印出一條消息。到目前為止,給出了觀察者模式的一個(gè)簡單用例。不過,通過這個(gè)看似簡單的用例,我們了解到在這種情況下控制是如何實(shí)現(xiàn)反轉(zhuǎn)的。

      觀察者模式下,主題就是起到”框架層“的作用,它完全主導(dǎo)何時(shí)何地去觸發(fā)誰的調(diào)用。觀察者的主動(dòng)權(quán)被外放,因?yàn)橛^察者無法主導(dǎo)自己何時(shí)被調(diào)用(只要它們已經(jīng)被注冊(cè)到某個(gè)主題中的話)。這意味著,實(shí)際上我們可以發(fā)現(xiàn)控制被反轉(zhuǎn)的”事發(fā)地“ – - – 當(dāng)觀察者綁定到主題時(shí):

      user.addObserver(() -> System.out.println(
            "Observable subject " + user + " has changed its state."));

      上述用例,簡要說明了為什么,觀察者模式(或GUI驅(qū)動(dòng)環(huán)境中的action監(jiān)聽器)是實(shí)現(xiàn)IoC的一種非常簡單的方式。正是以這種分散式設(shè)計(jì)軟件組件的形式,使得控制得以發(fā)生反轉(zhuǎn)。

      通過模板方法模式實(shí)現(xiàn)IoC

      模板方法模式實(shí)現(xiàn)的思想是在一個(gè)基類中通過幾個(gè)抽象方法(也稱算法步驟)來定義一個(gè)通用的算法,然后讓子類提供具體的實(shí)現(xiàn),這樣保證算法結(jié)構(gòu)不變。

      我們可以應(yīng)用這個(gè)思想,定義一個(gè)通用的算法來處理領(lǐng)域?qū)嶓w:

      public abstract class EntityProcessor {
       
        public final void processEntity() {
          getEntityData();
          createEntity();
          validateEntity();
          persistEntity();
        }
       
        protected abstract void getEntityData();
        protected abstract void createEntity();
        protected abstract void validateEntity();
        protected abstract void persistEntity();
       
      }

      processEntity() 方法是個(gè)模板方法,它定義了處理實(shí)體的算法,而抽象方法代表了算法的步驟,它們必須在子類中實(shí)現(xiàn)。通過多次繼承 EntityProcessor 并實(shí)現(xiàn)不同的抽象方法,可以實(shí)現(xiàn)若干算法版本。

      雖然這說清楚了模板方法模式背后的動(dòng)機(jī),但人們可能想知道為什么這是 IoC 的模式。

      典型的繼承中,子類調(diào)用基類中定義的方法。而這種模式下,相對(duì)真實(shí)的情況是:子類實(shí)現(xiàn)的方法(算法步驟)被基類的模板方法調(diào)用。因此,控制實(shí)際是在基類中進(jìn)行的,而不是在子類中。
      這也是 IoC 的典型例子,通過分層結(jié)構(gòu)實(shí)現(xiàn)。這種情況下,模板方法只是可調(diào)的擴(kuò)展點(diǎn)的一個(gè)漂亮的名字,被開發(fā)者用來管理自己的一系列實(shí)現(xiàn)。

      關(guān)于如何在Java中利用IOC控制反轉(zhuǎn)就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。


      本文標(biāo)題:如何在Java中利用IOC控制反轉(zhuǎn)-創(chuàng)新互聯(lián)
      轉(zhuǎn)載來于:http://ef60e0e.cn/article/jhpcc.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        株洲市| 乐都县| 灵川县| 卢龙县| 长白| 兴海县| 游戏| 盐边县| 东港市| 北海市| 蒲江县| 沂南县| 陆丰市| 长垣县| 锡林郭勒盟| 开阳县| 化德县| 威宁| 东海县| 渑池县| 华安县| 砀山县| 额敏县| 亚东县| 嘉祥县| 霍林郭勒市| 绿春县| 香港 | 察隅县| 林口县| 永嘉县| 安西县| 资源县| 丹东市| 广昌县| 镇江市| 基隆市| 黄山市| 霍邱县| 镇坪县| 吉水县|