Pengembangan Java yang lebih cerdas

Skema cepat dan sederhana untuk mempercepat pengembangan aplikasi Java skala besar melibatkan penggunaan antarmuka. Antarmuka Java adalah cetak biru untuk fungsionalitas yang terdapat dalam objek terkait.

Dengan memasukkan antarmuka ke dalam proyek Anda berikutnya, Anda akan melihat manfaatnya selama siklus hidup upaya pengembangan Anda. Teknik pengkodean ke antarmuka daripada objek akan meningkatkan efisiensi tim pengembangan dengan:

  • Memungkinkan tim pengembangan untuk dengan cepat membangun interaksi di antara objek yang diperlukan, tanpa memaksakan definisi awal dari objek pendukung
  • Memungkinkan pengembang untuk berkonsentrasi pada tugas pengembangan mereka dengan pengetahuan bahwa integrasi telah diperhitungkan
  • Memberikan fleksibilitas sehingga implementasi baru dari antarmuka dapat ditambahkan ke sistem yang ada tanpa modifikasi kode utama
  • Menegakkan kontrak yang disepakati oleh anggota tim pengembangan untuk memastikan bahwa semua objek berinteraksi seperti yang dirancang

Gambaran

Karena upaya pengembangan berorientasi objek melibatkan interaksi objek, maka penting untuk mengembangkan dan menegakkan kontrak yang kuat antara objek tersebut. Teknik pengkodean ke antarmuka melibatkan penggunaan antarmuka, bukan objek, sebagai metode komunikasi utama.

Artikel ini akan mengenalkan pengguna pada konsep pengkodean ke antarmuka melalui contoh sederhana. Contoh rinci akan mengikuti, membantu menunjukkan nilai skema ini dalam sistem yang lebih besar yang membutuhkan banyak pengembang. Namun, sebelum kita sampai ke kode sampel, mari kita lihat manfaat pengkodean ke antarmuka.

Mengapa kode ke antarmuka?

Antarmuka Java adalah kontrak pengembangan. Ini memastikan bahwa objek tertentu memenuhi serangkaian metode tertentu. Antarmuka digunakan di seluruh Java API untuk menentukan fungsionalitas yang diperlukan untuk interaksi objek. Contoh penggunaan antarmuka adalah mekanisme panggilan balik ( Event Listeners), pola ( Observer), dan spesifikasi ( Runnable, Serializable).

Pengkodean ke antarmuka adalah teknik di mana pengembang dapat mengekspos metode tertentu dari suatu objek ke objek lain dalam sistem. Pengembang yang menerima implementasi antarmuka ini memiliki kemampuan untuk mengkodekan antarmuka sebagai pengganti pengkodean ke objek itu sendiri. Dengan kata lain, pengembang akan menulis kode yang tidak berinteraksi langsung dengan objek, melainkan dengan implementasi antarmuka objek tersebut.

Alasan lain untuk membuat kode ke antarmuka daripada ke objek adalah karena kode memberikan efisiensi yang lebih tinggi dalam berbagai fase siklus hidup sistem:

  • Desain : metode suatu objek dapat dengan cepat ditentukan dan dipublikasikan ke semua pengembang yang terpengaruh
  • Pengembangan : compiler Java menjamin bahwa semua metode antarmuka diimplementasikan dengan tanda tangan yang benar dan semua perubahan pada antarmuka segera terlihat oleh pengembang lain.
  • Integrasi : ada kemampuan untuk menghubungkan kelas atau subsistem bersama-sama dengan cepat, karena antarmuka yang mapan
  • Pengujian : antarmuka membantu mengisolasi bug karena mereka membatasi ruang lingkup kesalahan logika yang mungkin terjadi pada subset metode tertentu

Ada beberapa overhead yang terkait dengan teknik pengembangan ini, karena infrastruktur kode yang diperlukan. Infrastruktur ini mencakup antarmuka untuk interaksi antara objek dan kode pemanggilan untuk membuat implementasi antarmuka. Overhead ini tidak signifikan jika dibandingkan dengan kemudahan dan manfaat menggunakan antarmuka seperti yang dijelaskan.

Contoh dasar

Untuk lebih menjelaskan konsep pengkodean ke antarmuka, saya telah membuat contoh sederhana. Meskipun contoh ini jelas-jelas sepele, ini menunjukkan beberapa manfaat yang disebutkan di atas.

Pertimbangkan contoh sederhana dari kelas Caryang mengimplementasikan antarmuka Vehicle. Antarmuka Vehiclememiliki satu metode yang disebut start(). Kelas Carakan mengimplementasikan antarmuka dengan menyediakan start()metode. Fungsi lain di Carkelas telah ditinggalkan demi kejelasan.

interface Vehicle {// Semua implementasi kendaraan harus mengimplementasikan metode start public void start (); } kelas Mobil mengimplementasikan Kendaraan {// Diperlukan untuk mengimplementasikan Kendaraan public void start () {...}}

Setelah meletakkan fondasi Carobjek, kita dapat membuat objek lain yang disebut Valet. Ini adalah Valettugas untuk memulai Cardan membawanya ke pelindung restoran. The Valetobjek dapat ditulis tanpa interface, sebagai berikut:

kelas Valet {mobil umum getCar (Mobil c) {...}} 

The Valetobjek memiliki metode yang disebut getCaryang mengembalikan sebuah Carobjek. Contoh kode ini memenuhi persyaratan fungsional sistem, tetapi selamanya menghubungkan Valetobjek dengan yang ada di Car. Dalam situasi ini, kedua benda tersebut dikatakan berpasangan erat. The Valetobjek membutuhkan pengetahuan tentang Carobjek dan memiliki akses ke semua metode umum dan variabel yang terkandung dalam objek tersebut. Cara terbaik adalah menghindari penggandengan kode yang begitu ketat karena meningkatkan ketergantungan dan mengurangi fleksibilitas.

Untuk mengkode Valetobjek menggunakan antarmuka, implementasi berikut dapat digunakan:

kelas Valet {Kendaraan umum getVehicle (Kendaraan c) {...}} 

Sementara perubahan kode cukup kecil - mengubah referensi dari Carmenjadi Vehicle- efek pada siklus pengembangan cukup besar. Menggunakan implementasi kedua, Valetmereka hanya memiliki pengetahuan tentang metode dan variabel yang ditentukan dalam Vehicleantarmuka. Metode dan data publik lainnya yang terdapat dalam implementasi spesifik Vehicleantarmuka disembunyikan dari pengguna Vehicleobjek.

Perubahan kode sederhana ini telah memastikan penyembunyian informasi dan implementasi yang tepat dari objek lain, dan karena itu menghilangkan kemungkinan bahwa pengembang akan menggunakan metode yang tidak diinginkan.

Membuat objek antarmuka

Masalah terakhir yang dibahas sehubungan dengan teknik pengembangan ini adalah pembuatan objek antarmuka. Meskipun dimungkinkan untuk membuat instance baru dari kelas menggunakan newoperator, tidak mungkin untuk membuat instance antarmuka secara langsung. Untuk membuat implementasi antarmuka, Anda harus membuat instance objek dan mentransmisikannya ke antarmuka yang diinginkan. Oleh karena itu, pengembang yang memiliki kode objek dapat bertanggung jawab untuk membuat instance objek dan melakukan casting.

Proses pembuatan ini dapat dicapai dengan menggunakan Factorypola di mana objek eksternal memanggil createXYZ()metode statis pada Factorydan mengembalikan antarmuka. Ini juga bisa dicapai jika pengembang memanggil metode pada objek lain dan meneruskannya ke antarmuka alih-alih kelas yang sebenarnya. Ini akan dianalogikan dengan melewatkan Enumerationantarmuka alih-alih Vectoratau Hashtable.

Contoh rinci

Untuk mendemonstrasikan penggunaan skema ini pada proyek yang lebih besar, saya telah membuat contoh penjadwal pertemuan. Penjadwal ini memiliki tiga komponen utama: sumber daya (ruang konferensi dan peserta rapat), kejadian (rapat itu sendiri) dan penjadwal (orang yang mengelola kalender sumber daya).

Mari kita asumsikan ketiga komponen ini dikembangkan oleh tiga pengembang yang berbeda. Tujuan setiap pengembang harus menetapkan penggunaan komponennya dan mempublikasikannya ke pengembang lain di proyek.

Perhatikan contoh a Person. A Persondapat mengimplementasikan banyak metode tetapi akan mengimplementasikan Resourceantarmuka untuk aplikasi ini. Saya telah membuat Resourceantarmuka dengan semua metode pengakses yang diperlukan untuk semua sumber daya yang digunakan dalam contoh ini (ditampilkan di bawah):

Sumber daya antarmuka publik {public String getID (); public String getName (); public void addOccurrence (Kejadian o); }

At this point, the developer of the Person functionality has published the interface by which all users can access the information stored in the Person object. Coding to the interface helps ensure that no developers are using the Person object in an incorrect manner. The developer of the Scheduler object can now use the methods contained in the Resource interface to access the information and functionality necessary to create and maintain the schedule of the Person object.

The Occurrence interface contains methods necessary for the scheduling of an Occurrence. This can be a conference, travel plan, or any other scheduling event. The Occurrence interface is shown below:

public interface Occurrence { public void setEndDatetime(Date d); public Date getEndDatetime(); public void setStartDatetime(Date d); public Date getStartDatetime(); public void setDescription(String description); public String getDescription(); public void addResource(Resource r); public Resource[] getResources(); public boolean occursOn( Date d); } 

The Scheduler code uses the Resource interface and the Occurrence interface to maintain the schedule of a resource. Notice that the Scheduler does not have any knowledge of the entity for which it is maintaining the schedule:

public class Scheduler implements Schedule{ Vector schedule = null; public Scheduler(){ schedule = new Vector(); } public void addOccurrence(Occurrence o){ schedule.addElement(o); } public void removeOccurrence(Occurrence o){ schedule.removeElement(o); } public Occurrence getOccurrence(Date d) { Enumeration scheduleElements = schedule.elements(); Occurrence o = null; while ( scheduleElements.hasMoreElements() ) { o = (Occurrence) scheduleElements.nextElement(); // For this simple example, the occurrence matches if // the datetime isthe meeting start time. This logic // can be made more complex as required. if ( o.getStartDatetime() == d) { break; } } return o; } } 

This example shows the power of interfaces in the development phases of a system. Each of the subsystems has knowledge only of the interface through which it must communicate -- no knowledge of the implementation is required. If each of the building blocks in the above example were to be further developed by teams of developers, their efforts would be simplified due to the enforcement of these interface contracts.

Final thoughts on interfaces

This article has demonstrated some of the benefits of coding to interfaces. This technique enables greater efficiency throughout each phase of the development lifecycle.

During the design phases of the project, interfaces allow the quick establishment of the desired interactions among objects. The implementation objects associated with a given interface can be defined after the methods and requirements for that interface are specified. The more quickly the interaction is established, the more quickly the design phase can progress into development.

Interfaces give developers the ability to expose and limit certain methods and information to the users of their objects without changing the permissions and internal structure of the object itself. The use of interfaces can help eliminate the pesky bugs that appear when code developed by multiple development teams is integrated.

Contract enforcement is provided by the interface. Because the interface is generally agreed upon during the design phase of the project, the developers have the ability to concentrate on their individual modules without having to worry about the modules of their colleagues. Integrating these subsystems is made more efficient by the fact that the contracts have already been enforced throughout the development phase.

For testing purposes, a simple driver object can be created to implement the agreed-upon interfaces. Using this object, developers can continue their work with the knowledge that they are using the proper methods to access the object. When the objects are deployed in a test environment, the driver classes are replaced by the true classes, allowing the object to be tested without code or property changes.

This scheme provides the capability for easy expansion of this system; in our example, we could expand the code to include more forms of resources, such as meeting rooms and audio/video equipment. Any additional implementation of the Resource interface will fit into the established mechanism without modifying the existing code. Large-scale projects using this scheme could be designed and implemented in such a way that additional functionality can be added without major modification to the infrastructure. As an example, the ConferenceRoom object was created. This object implements the Resource interface and can interact with the Schedule and Occurrence implementers without changing the infrastructure.

Manfaat lainnya adalah lokasi kode yang terpusat. Jika metode baru akan ditambahkan ke Resourceantarmuka, semua implementasi antarmuka ini akan diidentifikasi sebagai memerlukan perubahan. Ini akan mengurangi penyelidikan yang diperlukan untuk menentukan kemungkinan dampak perubahan pada antarmuka.

Selain manfaat pengembangan, teknik yang disajikan dalam artikel ini memberikan jaminan kepada manajemen proyek bahwa pola komunikasi antar objek atau antar sistem telah ditetapkan dan diterapkan di seluruh siklus pengembangan. Ini mengurangi risiko kegagalan selama fase integrasi dan pengujian proyek.