JavaRush /Java Blog /Random-TW /設計模式適配器

設計模式適配器

在 Random-TW 群組發布
你好!今天我們將觸及一個重要的新議題——模式,或者說——設計模式。什麼是模式?我想你知道「不要重新發明輪子」這句話。與許多其他領域一樣,程式設計中也存在大量典型情況。對於他們每個人來說,在程式開發過程中,都創造了現成的工作解決方案。這些是設計模式。相對而言,模式是一個特定的例子,它為以下情況提供了解決方案:“如果你的程式需要做某事,如何最好地做它。” 模式很多,一本優秀的書《學習設計模式》是專門針對它們的,你絕對應該閱讀。 設計模式“適配器”- 2簡而言之,模式由一個常見問題及其解決方案組成,這已經可以被認為是一種標準。在今天的講座中,我們將熟悉其中一種稱為「適配器」的模式。它的名字就很能說明問題,您在現實生活中不只一次遇到適配器。最常見的適配器之一是讀卡器,許多電腦和筆記型電腦都配備有讀卡機。 設計模式“適配器”- 3想像一下我們有某種記憶卡。問題是什麼? 事實是她不知道如何與電腦互動。它們沒有通用的介面。 電腦具有 USB 接口,但無法將記憶卡插入其中。該卡無法插入電腦,因此我們將無法保存我們的照片、影片和其他資料。讀卡機就是解決這個問題的轉接器。畢竟,它有 USB 電纜!與卡片本身不同,讀卡機可以插入電腦中。它們與電腦有一個共同的介面—USB。讓我們透過一個例子來看看它是什麼樣子的:
public interface USB {

   void connectWithUsbCable();
}
這是我們的USB接口,唯一的方法就是插入USB線:
public class MemoryCard {

   public void insert() {
       System.out.println("Карта памяти успешно вставлена!");
   }

   public void copyData() {
       System.out.println("Данные скопированы на компьютер!");
   }
}
這是我們實作記憶體映射的類別。它已經有我們需要的 2 個方法,但問題是:它沒有實作 USB 連接埠。該卡無法插入 USB 插槽。
public class CardReader implements USB {

   private MemoryCard memoryCard;

   public CardReader(MemoryCard memoryCard) {
       this.memoryCard = memoryCard;
   }

   @Override
   public void connectWithUsbCable() {
       this.memoryCard.insert();
       this.memoryCard.copyData();
   }
}
這是我們的適配器!該類別的CardReader作用是什麼?為什麼它是一個適配器?這很簡單。正在適配的類別(記憶體映射)成為適配器的欄位之一。這是符合邏輯的,因為在現實生活中我們也會將卡片插入讀卡機內部,它也成為讀卡機的一部分。與記憶卡不同,適配器具有與電腦的通用介面。它有一條 USB 電纜,這意味著它可以透過 USB 連接到其他裝置。因此,在程式中,我們的類別CardReader實作了USB介面。但是這個方法內部發生了什麼事?而我們所需要的正是發生了!適配器將工作委託給我們的記憶卡。畢竟,適配器本身不做任何事情;讀卡機沒有任何獨立的功能。它的工作只是連結電腦和記憶卡,以便卡可以完成其工作並複製文件!我們的適配器透過connectWithUsbCable()為記憶卡的「需求」提供自己的介面(方法)來實現這一點。讓我們創建某種客戶端程式來模擬想要從記憶卡複製資料的人:
public class Main {

   public static void main(String[] args) {

       USB cardReader = new CardReader(new MemoryCard());
       cardReader.connectWithUsbCable();

   }
}
結果我們得到了什麼?控制台輸出:
Карта памяти успешно вставлена!
Данные скопированы на компьютер!
太好了,我們的任務圓滿完成了!以下是一些附加鏈接,其中包含有關適配器模式的資訊:

抽象類別 Reader 和 Writer

現在我們將回到我們最喜歡的消遣:我們將學習一些用於處理輸入和輸出的新課程:)我想知道我們已經學了多少?今天我們來談談課程ReaderWriter。為什麼是他們呢?因為這會和我們之前的部分——適配器相關。讓我們更詳細地看看它們。讓我們從Reader「a」開始。 Reader是一個抽象類,因此我們無法明確地建立它的物件。 但事實上,你已經認識他了!畢竟,您熟悉的類別BufferedReaderInputStreamReader它的繼承人:)
public class BufferedReader extends Reader {}

public class InputStreamReader extends Reader {}
所以,類別InputStreamReader是一個經典的適配器。您可能還記得,我們​​可以將物件傳遞給其建構函數InputStream。大多數情況下,我們使用變數來實現這一點System.in
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
它有什麼作用InputStreamReader與任何適配器一樣,它將一種介面轉換為另一種介面。在這種情況下,接口InputStream'a到接口Reader'a。最初我們有一個班InputStream。它運行良好,但只能讀取單個位元組。此外,我們還有一個抽象類別Reader。它具有我們真正需要的出色功能 - 它可以讀取字元!當然,我們確實需要這個機會。但這裡我們面臨著適配器通常解決的一個經典問題——介面不相容。它是如何體現出來的?讓我們直接看一下 Oracle 文件。以下是類別方法InputStreamПаттерн проектирования «Адаптер» - 4一組方法就是一個介面。如您所看到的,read()此類有一個方法(即使在多個版本中),但它只能讀取位元組:單一位元組或使用緩衝區的多個位元組。這個選項不適合我們——我們想要讀取字元。我們需要的功能已經在抽象類別中實現了Reader。這也可以在文檔中看到。 Паттерн проектирования «Адаптер» - 5然而,InputStream“a”和Reader“a”介面不相容!可以看到,在所有的方法實作中,read()傳遞的參數和回傳值都是不同的。這就是我們需要它的地方InputStreamReader!他將充當我們類別之間的適配器。正如我們上面看到的讀卡機範例一樣,我們「在內部」傳遞「適配」類別的對象,也就是傳遞給適配器類別的建構子。在前面的範例中,我們MemoryCard在 內部傳遞了一個物件CardReader。現在我們將物件傳遞InputStream給建構函數InputStreamReader!作為一個質量,InputStream我們使用已經熟悉的變數System.in
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
事實上:透過查看文檔,InputStreamReader我們將看到「適應」是成功的:)現在我們擁有了可以讀取字元的方法。 Паттерн проектирования «Адаптер» - 6儘管最初我們的物件System.in(綁定到鍵盤的線程)不允許這樣做,但透過建立適配器模式,該語言的創建者解決了這個問題。Reader與大多數 I/O 類別一樣,抽象類別有一個孿生兄弟 - Writer。它具有同樣大的優點Reader- 它提供了一個方便的介面來處理符號。對於輸出流,問題及其解決方案看起來與輸入流的情況相同。有一個類別OutputStream只能寫位元組;有一個Writer可以使用符號的抽象類,並且有兩個不相容的介面。這個問題再次被Adapter模式成功解決。使用類,OutputStreamWriter我們可以輕鬆地使兩個類別介面彼此「適應WriterOutputStream。而且,在構造函數中接收到字節流後OutputStream,在幫助下OutputStreamWriter我們可以寫入字符,而不是字節!
import java.io.*;

public class Main {

   public static void main(String[] args) throws IOException {

       OutputStreamWriter streamWriter = new OutputStreamWriter(new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt"));
       streamWriter.write(32144);
       streamWriter.close();
   }
}
我們在文件中寫入了一個代碼為 32144 - 綐 的字符,從而消除了使用字節的需要:) 今天就這些,我們下節課見!:)
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION