CodeGym /Blog Java /rawak /Corak reka bentuk penyesuai
John Squirrels
Tahap
San Francisco

Corak reka bentuk penyesuai

Diterbitkan dalam kumpulan
Hai! Hari ini kita akan menyentuh topik baharu yang penting: corak reka bentuk . Apakah corak-corak ini? Saya rasa anda mesti tahu ungkapan " jangan cipta semula roda ". Dalam pengaturcaraan, seperti dalam banyak kawasan lain, terdapat sejumlah besar situasi biasa. Memandangkan pembangunan perisian telah berkembang, penyelesaian siap sedia yang berfungsi telah dicipta untuk setiap satu daripadanya. Penyelesaian ini dipanggil corak reka bentuk. Mengikut konvensyen, corak ialah beberapa penyelesaian yang dirumuskan seperti ini: "jika anda perlu melakukan X dalam program anda, maka ini adalah cara terbaik untuk melakukannya". Terdapat banyak corak. Buku yang sangat baik "Kepala Corak Reka Bentuk Pertama", yang anda pasti akan biasa dengannya, didedikasikan untuk mereka. Corak reka bentuk penyesuai - 2Secara ringkasnya, corak terdiri daripada masalah biasa dan penyelesaian sepadan yang boleh dianggap sebagai sejenis piawai. Dalam pelajaran hari ini, kita akan menemui salah satu daripada corak ini: Penyesuai. Namanya menyatakan semuanya, dan anda telah menemui penyesuai berkali-kali dalam kehidupan sebenar. Beberapa penyesuai yang paling biasa ialah pembaca kad yang dimiliki oleh banyak komputer dan komputer riba. Corak reka bentuk penyesuai - 3Katakan kita mempunyai sejenis kad memori. Jadi apa masalahnya? Ia tidak tahu bagaimana untuk berinteraksi dengan komputer. Mereka tidak berkongsi antara muka biasa. Komputer mempunyai port USB, tetapi kami tidak boleh memasukkan kad memori di dalamnya. Kad tidak boleh dipalamkan ke dalam komputer, jadi kami tidak dapat menyimpan foto, video dan data kami yang lain. Pembaca kad ialah penyesuai yang menyelesaikan masalah ini. Lagipun, ia mempunyai kabel USB! Tidak seperti kad itu sendiri, pembaca kad boleh dipasang ke dalam komputer. Mereka berkongsi antara muka biasa dengan komputer: USB. Mari lihat bagaimana ini kelihatan dalam amalan:

public interface USB { 

   void connectWithUsbCable(); 
}
Ini ialah antara muka USB kami dengan hanya satu kaedah untuk menyambung melalui 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!"); 
   } 
}
Ini adalah kelas kami yang mewakili kad memori. Ia sudah mempunyai 2 kaedah yang kami perlukan, tetapi inilah masalahnya: Ia tidak melaksanakan antara muka USB. Kad tidak boleh dimasukkan ke dalam port 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(); 
   } 
}
Dan inilah penyesuai kami! Apa yangCardReaderkelas lakukan dan apa sebenarnya yang menjadikannya penyesuai? Semuanya mudah. Kelas yang disesuaikan (MemoryCard) menjadi salah satu medan penyesuai. Ini masuk akal. Apabila kita meletakkan kad memori di dalam pembaca kad dalam kehidupan sebenar, ia juga menjadi sebahagian daripadanya. Tidak seperti kad memori, penyesuai berkongsi antara muka dengan komputer. Ia mempunyai kabel USB, iaitu ia boleh disambungkan ke peranti lain melalui USB. Itulah sebabnya kelas CardReader kami melaksanakan antara muka USB. Tetapi apa sebenarnya yang berlaku dalam kaedah ini? Tepat apa yang kita perlu berlaku! Penyesuai mewakilkan kerja ke kad memori kami. Sesungguhnya, penyesuai tidak melakukan apa-apa sendiri. Pembaca kad tidak mempunyai sebarang fungsi bebas. Tugasnya hanya untuk menyambungkan komputer dan kad memori untuk membolehkan kad melakukan kerjanya — menyalin fail!connectWithUsbCable()kaedah) untuk memenuhi "keperluan" kad memori. Mari buat beberapa program klien yang akan meniru seseorang yang ingin menyalin data daripada kad memori:

public class Main { 

   public static void main(String[] args) { 

       USB cardReader = new CardReader(new MemoryCard()); 
       cardReader.connectWithUsbCable(); 
   } 
}
Jadi apa yang kita dapat? Output konsol:

Memory card successfully inserted! 
The data has been copied to the computer!
Cemerlang. Kami mencapai objektif kami! Berikut ialah pautan ke video dengan maklumat tentang corak Penyesuai:

Kelas abstrak Pembaca dan Penulis

Sekarang kita akan kembali ke aktiviti kegemaran kita: belajar tentang beberapa kelas baharu untuk bekerja dengan input dan output :) Saya tertanya-tanya berapa banyak yang telah kita pelajari. Hari ini kita akan bercakap tentang Reader dan Writerkelas. Mengapa khusus kelas tersebut? Kerana ia berkaitan dengan bahagian kami sebelumnya tentang penyesuai. Mari kita periksa mereka dengan lebih terperinci. Kita akan mulakan dengan  Reader. Readerialah kelas abstrak, jadi kami tidak akan dapat mencipta objek secara eksplisit.   Tetapi anda sebenarnya sudah biasa dengannya! Lagipun, anda sudah biasa dengan kelas BufferedReaderdan InputStreamReader, yang merupakan keturunannya :)

public class BufferedReader extends Reader { 
… 
} 

public class InputStreamReader extends Reader { 
… 
}
Kelas ini InputStreamReaderialah penyesuai klasik. Seperti yang anda mungkin ingat, kita boleh menghantar InputStreamobjek kepada pembinanya. Untuk melakukan ini, kami biasanya menggunakan pembolehubah System.in:

public static void main(String[] args) { 

   InputStreamReader inputStreamReader = new InputStreamReader(System.in); 
}
Tetapi apa yang InputStreamReaderdilakukan? Seperti setiap penyesuai, ia menukar satu antara muka kepada yang lain.  Dalam kes ini, InputStreamantara muka ke Readerantara muka. Pada mulanya, kami mempunyai InputStreamkelas. Ia berfungsi dengan baik, tetapi anda hanya boleh menggunakannya untuk membaca bait individu. Di samping itu, kami mempunyai Readerkelas abstrak. Ia mempunyai beberapa fungsi yang sangat berguna — ia tahu cara membaca aksara! Kita pasti memerlukan keupayaan ini. Tetapi di sini kita menghadapi masalah klasik yang biasanya diselesaikan oleh penyesuai — antara muka yang tidak serasi. Apakah maksudnya? Mari kita lihat dokumentasi Oracle. Berikut adalah kaedah kelas InputStream. Corak reka bentuk penyesuai - 4Satu set kaedah adalah tepat apa itu antara muka. Seperti yang anda lihat, kelas ini mempunyai aread()kaedah (sebenarnya beberapa varian), tetapi ia hanya boleh membaca bait: sama ada bait individu, atau beberapa bait menggunakan penimbal. Tetapi pilihan ini tidak sesuai dengan kami — kami mahu membaca aksara. Kami memerlukan kefungsian yang telah dilaksanakan dalam Readerkelas abstrak . Kita juga boleh melihat ini dalam dokumentasi. Corak reka bentuk penyesuai - 5Walau bagaimanapun, antara muka InputStreamdan  Readertidak serasi! Seperti yang anda lihat, setiap pelaksanaan kaedah read()mempunyai parameter dan nilai pulangan yang berbeza. Dan di sinilah kita perlukan InputStreamReader! Ia akan bertindak sebagai penyesuai antara kelas kami. Seperti dalam contoh dengan pembaca kad, yang kami pertimbangkan di atas, kami meletakkan contoh kelas yang disesuaikan "di dalam" kelas penyesuai, iaitu kami menyerahkan satu kepada pembinanya. Dalam contoh sebelumnya, kami meletakkan MemoryCardobjek di dalam CardReader. Sekarang kita menghantar InputStream objek kepada InputStreamReaderpembina! Kami menggunakan System.inpembolehubah biasa kami sebagai InputStream:

public static void main(String[] args) { 

   InputStreamReader inputStreamReader = new InputStreamReader(System.in); 
}
Dan sememangnya, melihat dokumentasi untuk InputStreamReader, kita dapat melihat bahawa penyesuaian berjaya :) Kini kita mempunyai kaedah untuk membaca aksara yang kita gunakan. Corak reka bentuk penyesuai - 6Dan walaupun System.inobjek kami (strim yang terikat pada papan kekunci) pada mulanya tidak membenarkan ini, pencipta bahasa menyelesaikan masalah ini dengan melaksanakan corak penyesuai. Kelas Readerabstrak, seperti kebanyakan kelas I/O, mempunyai saudara kembar —  Writer. Ia mempunyai kelebihan besar yang sama seperti  Reader — ia menyediakan antara muka yang mudah untuk bekerja dengan aksara. Dengan aliran keluaran, masalah dan penyelesaiannya kelihatan sama seperti aliran input. Terdapat OutputStreamkelas yang hanya boleh menulis bait, terdapat aWriterkelas abstrak yang tahu cara bekerja dengan aksara, dan terdapat dua antara muka yang tidak serasi. Masalah ini sekali lagi diselesaikan oleh corak penyesuai. Kami menggunakan OutputStreamWriterkelas untuk menyesuaikan kedua-dua antara muka Writer dan  OutputStream kelas dengan mudah antara satu sama lain. Selepas menghantar OutputStreamaliran bait kepada pembina, kita boleh menggunakan a OutputStreamWriteruntuk menulis aksara dan bukannya bait!

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();
   } 
}
Kami menulis watak dengan kod 32144 (綐) pada fail kami, menghapuskan keperluan untuk berfungsi dengan bait :) Itu sahaja untuk hari ini. Jumpa anda dalam pelajaran seterusnya! :)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION