CodeGym /Java Blog /ランダム /アダプターの設計パターン
John Squirrels
レベル 41
San Francisco

アダプターの設計パターン

ランダム グループに公開済み
やあ!今日は、重要な新しいトピック「デザイン パターン」について触れます。これらのパターンは何ですか? 「車輪の再発明はしない」という言葉をご存知かと思います。他の多くの分野と同様、プログラミングにも、一般的な状況が多数あります。ソフトウェア開発が進化するにつれて、それぞれに適した既製のソリューションが作成されてきました。これらのソリューションはデザイン パターンと呼ばれます。慣習的に、パターンとは、「プログラムで X を実行する必要がある場合、これを行うための最良の方法である」というように定式化されたソリューションです。たくさんのパターンがあります。これらについては、ぜひよく知っておくべき優れた本『Head First Design Patterns』を参照してください。 アダプターの設計パターン - 2簡潔に言うと、パターンは、一種の標準とみなせる、共通の問題とそれに対応する解決策で構成されます。今日のレッスンでは、これらのパターンの 1 つであるアダプターについて説明します。名前がすべてを物語っていて、現実の生活でもアダプターに何度も遭遇したことがあります。最も一般的なアダプタには、多くのコンピュータやラップトップに搭載されているカード リーダーがあります。 アダプターの設計パターン - 3ある種のメモリカードがあるとします。だから問題は何ですか? コンピュータと対話する方法を知りません。これらは共通のインターフェイスを共有していません。 コンピュータには USB ポートがありますが、メモリ カードを挿入できません。カードをコンピュータに接続できないため、写真、ビデオ、その他のデータを保存できません。カードリーダーはこの問題を解決するアダプターです。なんといってもUSBケーブルが付いているからです!カード自体とは異なり、カード リーダーはコンピューターに接続できます。これらはコンピュータと共通のインターフェイスである USB を共有します。これが実際にどのようになるかを見てみましょう。

public interface USB { 

   void connectWithUsbCable(); 
}
これは、USB 経由で接続するための 1 つの方法だけを備えた USB インターフェイスです。

public class MemoryCard { 

   public void insert() { 
       System.out.println("Memory card successfully inserted!"); 
   } 

   public void copyData() { 
       System.out.println("The data has been copied to the computer!"); 
   } 
}
これはメモリカードを表すクラスです。必要な 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クラスは何をしますか?そしてそれがアダプターになるのは正確には何ですか? どれもシンプルです。適応されるクラス (MemoryCard) はアダプターのフィールドの 1 つになります。意味あり。実際にメモリカードをカードリーダーに入れると、メモリカードもカードリーダーの一部になります。メモリ カードとは異なり、アダプタはコンピュータとインターフェイスを共有します。USBケーブルが付属しており、USB経由で他のデバイスに接続できます。このため、CardReader クラスは USB インターフェイスを実装します。しかし、このメソッド内では一体何が起こっているのでしょうか? まさに私たちが起こすべきことなのです!アダプターは作業をメモリーカードに委任します。実際、アダプター自体は何も行いません。カード リーダーには独立した機能はありません。その仕事は、コンピュータとメモリ カードを接続して、カードがその作業、つまりファイルをコピーできるようにすることだけです。connectWithUsbCable()メソッド)メモリカードの「ニーズ」を満たすため。メモリ カードからデータをコピーしたい人をシミュレートするクライアント プログラムを作成しましょう。

public class Main { 

   public static void main(String[] args) { 

       USB cardReader = new CardReader(new MemoryCard()); 
       cardReader.connectWithUsbCable(); 
   } 
}
それで、私たちは何を手に入れたのでしょうか?コンソール出力:

Memory card successfully inserted! 
The data has been copied to the computer!
素晴らしい。目標を達成しました!アダプター パターンに関する情報を含むビデオへのリンクは次のとおりです。

Reader および Writer の抽象クラス

ここで、私たちのお気に入りのアクティビティに戻ります。入力と出力を操作するためのいくつかの新しいクラスについて学習します :) すでにいくつ学習したでしょうか。Reader 今日はとクラスについて話しますWriter。なぜ特にそれらのクラスなのでしょうか? これらはアダプターに関する前のセクションに関連しているためです。それらをさらに詳しく調べてみましょう。から始めましょう ReaderReaderは抽象クラスであるため、オブジェクトを明示的に作成することはできません。  しかし、実際にはすでによくご存知です。結局のところ、あなたはその子孫である BufferedReaderおよびクラスについてよく知っています:)InputStreamReader

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インターフェイスからインターフェイスへReader。まず、クラスがありますInputStream。これはうまく機能しますが、個々のバイトを読み取るためにのみ使用できます。さらに、Reader抽象クラスもあります。非常に便利な機能がいくつかあり、文字の読み方を知っています。私たちには確かにこの能力が必要です。しかしここで、通常はアダプターによって解決される古典的な問題、つまり互換性のないインターフェイスに直面します。どういう意味ですか?Oracle のドキュメントを見てみましょう。ここではクラスのメソッドを紹介しますInputStreamアダプターの設計パターン - 4メソッドのセットはまさにインターフェイスそのものです。ご覧のとおり、このクラスにはread()このメソッド (実際にはいくつかのバリエーション) を使用できますが、読み取ることができるのはバイトのみです。個々のバイト、またはバッファを使用した複数バイトのいずれかです。しかし、このオプションは私たちには適していません。私たちは文字を読みたいのです。抽象クラスにすでに実装されているReader機能が必要です。これはドキュメントでも確認できます。 アダプターの設計パターン - 5ただし、InputStreamと の Readerインターフェイスには互換性がありません。ご覧のとおり、read()メソッドの実装ごとに異なるパラメーターと戻り値があります。そしてここが私たちが必要とするところですInputStreamReader!これはクラス間の アダプターとして機能します。上で検討したカード リーダーの例と同様に、適応されるクラスのインスタンスをアダプター クラスの「内部」に置きます。つまり、インスタンスをそのコンストラクターに渡します。前の例では、MemoryCardオブジェクトを の中に入れましたCardReaderInputStream 次に、オブジェクトをコンストラクターに渡しますInputStreamReader。おなじみのSystem.in変数を次のように使用しますInputStream

public static void main(String[] args) { 

   InputStreamReader inputStreamReader = new InputStreamReader(System.in); 
}
そして実際、 のドキュメントを見るとInputStreamReader、適応が成功したことがわかります :) これで、自由に文字を読み取るメソッドができました。 アダプター設計パターン - 6そして、私たちのSystem.inオブジェクト (キーボードにバインドされたストリーム) は当初これを許可していませんでしたが、言語の作成者はアダプター パターンを実装することでこの問題を解決しました。Readerほとんどの I/O クラスと同様、抽象クラスには双子の兄弟 ( ) があり ますWriter。これには、キャラクターを操作するための便利なインターフェイスが提供されるという大きな利点もあります Reader 。出力ストリームの場合、問題とその解決策は入力ストリームの場合と同じように見えます。OutputStreamバイトしか書き込めないクラスがあります。Writer文字の操作方法を認識する抽象クラスと、互換性のないインターフェイスが 2 つあります。この問題もアダプター パターンによって解決されます。クラスを使用して、 と クラスOutputStreamWriterの 2 つのインターフェイスを 相互に簡単に適合させます。バイト ストリームをコンストラクターに渡した後、 を使用してバイトではなく文字を書き込むことができます。 WriterOutputStreamOutputStreamOutputStreamWriter

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