Java nesnesini neden uygulama yerine arabirim (örneğin Harita) kullanarak tanımlamanız gerekir?


17

Çoğu Java kodunda, insanların böyle Java nesneleri bildirdiklerini görüyorum:

Map<String, String> hashMap = new HashMap<>();
List<String> list = new ArrayList<>();

onun yerine:

HashMap<String, String> hashMap = new HashMap<>();
ArrayList<String> list = new ArrayList<>();

Java nesnesini gerçekte kullanılacak uygulama yerine arabirimi kullanarak tanımlamak neden tercih edilir?


Yanıtlar:


26

Bunun nedeni, bu arayüzlerin uygulanmasının genellikle onları işlerken ilgili olmamasıdır, bu nedenle arayanı HashMapbir yönteme geçmek zorunda bırakırsanız, esas olarak hangi uygulamanın kullanılacağını zorunlu kılarsınız. Genel bir kural olarak, gerçek uygulama yerine arayüzünü ele HashMapalmanız ve LinkedHashMapbunun yerine kullanmanız gerektiğine karar verdiğinizde tüm yöntem imzalarını değiştirmek zorunda kalabilecek acı ve acıdan kaçınmanız gerekir .

Uygulama söz konusu olduğunda bunun istisnaları olduğu söylenmelidir. Sırası önemli olduğunda bir harita gerekiyorsa, o zaman bir gerektirebilir TreeMapveya LinkedHashMapgeçirilen veya daha iyisi edilecek SortedMapbelirli uygulama belirtmez hangi. Bu mutlaka Haritasının uygulanması belirli bir tür geçmek arayan yükümlülüğü ve şiddetle o emir ipuçları olduğunu önemli. Bununla birlikte, SortedMapsıralanmamış olanı geçersiz kılabilir ve iletebilir misiniz ? Evet, elbette, sonuç olarak kötü şeylerin olmasını bekleriz.

Bununla birlikte, en iyi uygulama hala önemli değilse, belirli uygulamaları kullanmamanız gerektiğini belirtir. Bu genel olarak doğrudur. Eğer mirastan en iyi şekilde yararlanmak için uğraşıyorsanız Dogve Catbunlardan türetiyorsanız, Animalgenellikle Dogveya 'ya özgü yöntemler kullanmaktan kaçınmalısınız Cat. Aksine tüm yöntemler Dogveya Catyöntemleri geçersiz kılmalı Animalve uzun vadede sizi kurtaracaktır.


Sıralanan bir haritaya ihtiyacınız olduğunda, parametre türü olmamalı SortedMap, olmamalıdır TreeMap.
Cephalopod

@Arian SortedMap, siparişle ilgilenen birkaç uygulamadan biridir. Konunun dışında bu. TreeMapayrıca öğeleri anahtarın uygulanmasına Comparableveya bir Comparatorarayüze göre sipariş eder .
Neil

Hayır, SortedMap bir uygulama değildir, asıl mesele budur. Anahtarla sıralama yapan haritaların arabirimidir.
Kafadanbacaklı

1
@Arian Ah ne demek istediğini anlıyorum. Doğru, daha iyi SortedMap, çünkü bu bir uygulamayı zorlamaz. Doğru ayarları yapacağım.
Neil

Aslında, bir LinkedHashMapuygulama yok SortedMap. Sadece alt sınıfları SortedMapvardır ConcurrentSkipListMapve TreeMap.
bcorso

10

Layman'ın sözleriyle:

Aynı sebeple elektrikli ev aletleri üreticileri, ürünlerini sadece soyulmuş kablolar yerine elektrik prizleri ile inşa ettiler ve evler, duvardan yapışan kablolar yerine duvar prizleri ile geliyorlar.

Bunun yerine standart fişler kullanarak, aynı aparatları evin etrafındaki herhangi bir uyumlu fişe takmayı sağlarlar.

Duvar prizinin bakış açısından, bir TV seti veya stereo takmanız önemli değildir.

Bu hem cihazı hem de prizi daha kullanışlı hale getirir.

Örneğin, bir haritayı argüman olarak kabul eden bir yöntemi ele alalım.

Yöntem, bir HashMap veya LinkedHashMap'i ona aktardığınıza bakılmaksızın çalışır, Harita'nın bir alt sınıfı olduğu sürece.

Bu Liskov oyuncu değiştirme ilkesi .

Verdiğiniz örnek kodda, daha sonra bir nedenden dolayı Hash'in somut uygulamasını değiştirebileceğiniz ve kodun geri kalanını değiştirmeniz gerekmeyeceği anlamına gelir.

Yazılımdaki sorun, daha sonra tuğla veya harç kaybı olmadan bir şeyleri değiştirmek nispeten kolay olduğundan, insanlar bu tür ön düşünmenin zaman ayırmaya değer olmadığını varsayarlar. Ancak gerçeklik bize yazılım bakımının çok pahalı olduğunu gösterdi.


4

Arayüz ayırma prensibine ( SOLID'de 'I' ) uymaktır . Bu nesneleri kullanan kodun, ihtiyaç duymadığı nesnelerin yöntemlerine bağlı olmasını engeller, bu da kodu daha az eşleşir ve bu nedenle değiştirmeyi kolaylaştırır.

Örneğin, daha sonra gerçekten bir a'ya ihtiyacınız LinkedHashMapolduğunu öğrenirseniz, başka bir kodu etkilemeden bu değişikliği güvenle yapabilirsiniz.

Ancak, bir değiş tokuş vardır, çünkü nesneyi parametre olarak alabilecek kodu yapay olarak sınırlandırıyorsunuz. Diyelim ki bir yerde bir sebep gerektiren bir fonksiyon var HashMap. A değerini döndürürseniz Map, nesnenizi bu işleve geçiremezsiniz. Gelecekte, daha somut bir sınıftaki ekstra işlevselliğe ihtiyaç duyma olasılığını, kuplajı sınırlama ve genel arayüzünüzü olabildiğince küçük tutma arzusuyla dengelemeniz gerekir.


3

Değişkenin bir arabirimle kısıtlanması, bu değişkenin kullanımlarından hiçbirinin arabirimde HashMapbulunmayan belirli işlevleri kullanmamasını sağlamaz, bu nedenle yeni örnek, arayüz.

Bu nedenle, bir nesne arabirimi kullanmak istediğinizde, değişkenlerinizi belirli bir uygulama olarak değil arabirim olarak bildirmek her zaman iyi bir uygulamadır, bu, kullanabileceğiniz bir arabirime sahip tüm nesne türleri için geçerlidir. Sık sık görmenizin nedeni, birçok insanın bunu bir alışkanlık olarak inşa etmesidir.

Bununla birlikte, bazen arayüzleri kullanmaktan atlamak zararlı değildir ve çoğumuz gerçek bir zarar vermeden her zaman bu kurala uymuyor. Kodun değişebileceğini ve gelecekte bakım / büyümeye ihtiyaç duyabileceğinizi hissettiğinizde sadık kalmak iyi bir uygulamadır. Uzun bir ömre sahip olacağından veya çok fazla önem taşıyacağından şüphelenmediğiniz bir kod hacklediğinizde daha az endişe duyarsınız. Ayrıca, bu kuralı kırmanın genellikle uygulamayı başka bir kuralla değiştirmenin biraz yeniden düzenleme gerektirebileceği gibi küçük bir sonucu vardır, bu nedenle her zaman izlemezseniz, kendinize çok zarar vermezsiniz, ancak onu takip etmede de gerçek bir zarar yoktur. .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.