Bir paketleyiciye çok sayıda düz geçiş işlevi yazmaktan nasıl kaçınırım?


13

Ortak bir temel türü başka bir sınıfı sarar bir sınıf var. Taban tipi arabirim oldukça büyük olduğundan, çok sayıda geçiş işlevi yazmayı içerir. Bundan kaçınmanın bir yolunu arıyorum.

Bir örnek verelim:

      Car
     /   \
Volvo     VolvoWithTrailer

Şimdi VolvoWithTrailer için araç arayüzündeki her bir işlevi uygulamak ve daha düşük bir şey döndürecek belki GetMaxSpeed ​​() dışında sarılmış Volvo nesnesindeki uygun işlevi çağırmak zorundayım. Temelde benim gibi birçok işlevi olacak

int VolvoWithTrailer::GetNumSeats() {
  return mVolvo.GetNumSeats()
}

Bunu çözmenin açık bir yolu, VolvoWithTrailer'ı bir Volvo alt sınıfı yapmak olacaktır

    Car
     |
   Volvo
     |
VolvoWithTrailer

ancak bu, miras yerine kompozisyonu tercih etme ilkesini ihlal ediyor gibi görünüyor.

Tüm bu paketleyicileri yazmaktan başka nasıl kaçınabilirim (dil C ++)? Ya da - eğer konumunuz buysa - neden onları yazmalıyım / sadece miras kullanmalıyım? Bu konuda yardımcı olabilecek herhangi bir şablon büyüsü var mı?


2
Bunu çok fazla düşünmedim ve Java'da düşünüyoruz. 'Treyler' arayüzü ne olacak? VolvoWithTrailer Volvo'yu genişletecek ve Treyler arayüzünü uygulayacak mı?

7
Kompozisyonu kalıtım yerine yalnızca mantıklı olduğunda tercih edin.
Robert Harvey

@RobertHarvey: +1. Bu bir rehberdir, bir "ilke" değildir ve kesinlikle mutlak bir emir değildir.
Mason Wheeler

Python'da bunu içgözlemle (C # yansıma olarak adlandırdığı şey) çözebilirsiniz.
user16764

1
IDE'niz kod oluşturmayı ele almıyor mu?
Amy Blankenship

Yanıtlar:


5

Benim düşüncem, programın uzun vadeli istikrarını ve sürdürülebilirliğini daha iyi hale getirmek için yazmanız gereken her şeyi yazmanız gerektiğidir . Bugün 20 satır kod yazmaktan kaçınmanın anlamı nedir, eğer bu kodu kullanan bir şeye her dokunduğunuzda veya bu Sınıfı korumak için geri döndüğünüzde, bugün zaman ayırmadığınız için size fazladan 5 dakika veya daha fazla ücret ödersiniz?

O zaman soru "ne yazman gerekiyor?" Bence yeterince bilgi sadece o bazı şeyleri listeleriz böylece, kesin bir cevap vermek mümkün sağlamak sanmıyorum ben bir karar içinde düşünmek olacaktır:

1. Trailer nesnesinin tek başına, şimdi veya öngörülebilir gelecekte olması gerekiyor mu?
Öyleyse, sarmalayıcıyı her iki kompozit nesnenin etrafında yapmak için oldukça iyi bir argümanınız var, çünkü zaten birini veya diğerini sarmanız gerekecek. Tutarlı da olabilir.

2. Kodun bir alanında geliştiricilerin sık sık girdiği veya böyle olması muhtemel olan üç alandan herhangi biri (Araba, Römork, CarWithTrailer) var mı?
Eğer öyleyse, çok dikkatli olun, çünkü yanlış olanı seçmenin sonuçları, koda her dokunulduğunda çok maliyetli olarak amorti edilebilir. Değilse, hiç birşey fark olmayabilir neyi siz karar verin. Sadece bir yön seç ve onunla git.

3. Anlaması en kolay olan nedir?
Bir yaklaşım size arkadan gelen birinin derhal yapmaya çalıştığınız şeyi "alacağını" söylüyor mu? Takım arkadaşlarınızın bir yaklaşımı sürdürmelerini zorlaştırabilecek belirli önyargıları var mı? Her şey eşitse, en düşük bilişsel yükü empoze eden çözümü seçin.

4. Bir yaklaşımı diğerine göre kullanmanın başka avantajları var mı?
Bana atlayan bir şey, CarWithTrailerWrapper'ınızın herhangi bir arabayı ve herhangi bir römorku bir CarWithTrailer'a sarılabileceğini yazarsanız, sarmalayıcı fikrinin belirgin bir avantajı olmasıdır. Ardından, tüm geçiş yöntemlerinizi yazmanız gerekir, ancak bunları her Araba Sınıfı için bir kez değil, yalnızca bir kez yazarsınız .

Bu, daha fazla Otomobil ve Römork ekledikçe doğrudan geçiş yöntemlerini yazma konusundaki ilk yatırımınızı daha ucuz hale getirir. Ayrıca, yalnızca bir uygulama ile daha fazlasını yapabileceğiniz için, işleri doğrudan Volvo veya VolvoWithTrailer ile birleştirmeye yönelik cazibenin azaltılmasına yardımcı olurken, CarWithTrailerWrapper'a bağlanmanın sonuçlarını da azaltır.

Belki de uzantı yöntemini kullanarak ücretsiz olarak alacağınız belirgin avantajlar vardır, ancak onları görmüyorum.

Tamam, bu yüzden önemsiz uygulamalar için kendimi ilerlemeye ve geçiş yöntemlerini doldurmaya doğru konuştuğum anlaşılıyor.

Ben bir C ++ programcısı değilim, bu yüzden hangi kod oluşturma araçlarının kullanabileceğiniz hakkında hiçbir fikrim yok. Kullandığım IDE, bir Arayüzden yöntemler üretebilir ve doğrudan geçişleri ağrısız hale getirecek kod şablonları ekleyebilirim . Bunu yapan bir IDE'ye erişiminiz yoksa, Excel'in sizin için kod yazmasına izin verebilirsiniz .


3

Taban tipi arabirim oldukça büyük olduğundan, çok sayıda geçiş işlevi yazmayı içerir.

Ve senin sorunun var.

Arabirimler yalnızca bir sorumluluğu üstlenmelidir. Bunları ince ve odaklanmış tutmak, dekoratör, proxy veya başka bir sarmalayıcıda (sınıfın kullanımını, test edilmesini, sürdürülmesini ve genişletilmesini kolaylaştırmanın yanı sıra) yapılması gereken geçiş işini de sınırlar.


5
Ah ne? Bir Sınıf birden fazla arabirim uygulayabilir ve arabirimler birbirinden miras alabilir. Bu nedenle, bir Arayüz oldukça küçük olsa bile, bunları uygulayan Sınıfların çok sayıda fonksiyona veya doğrudan fonksiyonlara ihtiyacı olup olmayacağı ile ilgisi yoktur. Daha küçük ve daha iyi tanımlanmış sınıflar , daha büyük olasılıkla o olur edecektir geçiş gerek fonksiyonları.
Amy Blankenship
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.