OOP'un ardındaki temel fikir, veri ve davranışların (bu veri üzerine) ayrılmaz olması ve sınıfın bir nesnesi fikri ile birleştirilmeleridir. Nesnenin bununla (ve diğer verilerle) çalışan veri ve yöntemleri vardır. Açıkça OOP ilkelerine göre, sadece veri olan nesneler (C yapılarına benzer) bir anti-kalıp olarak kabul edilir.
Çok uzak çok iyi.
Sorun şu ki, kodumun son zamanlarda bu anti-patern doğrultusunda gittikçe daha fazla gittiğini farkettim. Bana göre, sınıflar ve gevşek eşleşmiş tasarımlar arasında gizlenmeye daha fazla bilgi edinmeye çalıştığımda, sınıflarım daha fazla davranışsız, davranışsız ve tüm davranışsız veri sınıfları olarak saf veri karışımı oluyor.
Genellikle sınıfları, diğer sınıfların varlığına ilişkin farkındalıklarını en aza indirecek ve diğer sınıfların arayüzleri hakkındaki bilgilerini en aza indirecek şekilde tasarlarım. Bunu özellikle yukarıdan aşağıya bir zorla uygularım, daha düşük seviyeli sınıflar daha üst seviyeli sınıfları bilmez. Örneğin:
Genel bir kart oyunu API'niz olduğunu varsayalım. Senin bir sınıfın var Card
. Şimdi bu Card
sınıfın oyunculara görünürlüğü belirlemesi gerekiyor.
Tek yönlü sahip olmaktır boolean isVisible(Player p)
üzerine Card
sınıfa.
Başka sahip olmaktır boolean isVisible(Card c)
üzerine Player
sınıfa.
Özellikle birinci Player
sınıf sınıf hakkında daha düşük seviyeli bir Card
sınıfa bilgi verdiğinden ilk yaklaşımı beğenmedim .
Bunun yerine Viewport
, Player
hangi kartların görülebildiğini belirleyen bir ve bir liste listesi verilen bir sınıfa sahip olduğumuz üçüncü seçeneği tercih ettim .
Ancak bu yaklaşım hem soyar Card
ve Player
olası bir üye işlev sınıfları. Bunu, kartların görünürlüğünden başka şeyler için yaptığınızda, tüm işlevler çoğunlukla veri içermeyen sınıflar olan, yalnızca yöntemlerin olduğu gibi, yukarıdaki gibi yöntemlerle uygulandığından , geride bırakılırsınız Card
ve Player
tamamen veri içeren sınıflar kalırsınız Viewport
.
Bu açıkça OOP'nin ana fikrine karşıdır.
Hangisi doğru yolu? Sınıf bağımlılıklarını en aza indirme, varsayılan bilgi ve eşleşmeyi en aza indirme, ancak tüm düşük seviyeli sınıfların sadece veri içerdiği ve yüksek seviyeli sınıfların tüm yöntemleri içerdiği garip tasarıma gerek duymadan nasıl devam etmeliyim? Herhangi bir problemi ortadan kaldıran sınıf tasarımında üçüncü bir çözümü veya perspektifi olan var mı?
PS İşte başka bir örnek:
Değişmeyen bir sınıfa DocumentId
sahip olduğunuzu, BigDecimal id
bu üyeye sadece tek bir üye ve bir alıcı olduğunu varsayalım . Şimdi, bir yerde bu yönteme sahip olmalısınız, ki bu id için bir veri tabanından DocumentId
geri döner Document
.
Yapıyor musun:
- DB'ye ve benzerlerine erişmek için kullanılan API, tek tek ısrarlılığınız ( ) hakkında bilgi
Document getDocument(SqlSession)
vererek,DocumentId
sınıfa yöntem ekleyin"we're using a database and this query is used to retrieve document by id"
. Ayrıca bu sınıf şimdi sadece derlemek için sebat JAR dosyasını gerektirir. - Yöntemi içeren başka bir sınıf ekleyin
Document getDocument(DocumentId id)
,DocumentId
sınıfı ölü olarak bırakın, davranış yok, yapı benzeri sınıf.