Hangisi daha iyi: bir dizi alıcı veya seçim dizesi parametresi ile 1 yöntem?


15

Bilgi alanımız, çıplak ayaklarıyla bir baskı plakası üzerinde yürüyen insanları içerir. Sensör verilerinde bir insan ayağı tanınırsa, 'Foot' sınıfı nesnelerle sonuçlanan görüntü tanıma yaparız.

Ayağın verilerinde yapılması gereken birkaç hesaplama vardır.

Şimdi, hangi API daha iyi olurdu:

class Foot : public RecognizedObject  { 
  MaxPressureFrame getMaxPressureFrame();
  FootAxis getFootAxis();
  AnatomicalZones getAnatomicalZones();

  // + similar getters for other calculations

  // ...
}

Veya:

class Foot : public RecognizedObject {
  virtual CalculationBase getCalculation(QString aName);

  // ...
}

Şimdi, gelebileceğim birçok profesyonel ve con var, ama hangisinin en önemli olduğuna gerçekten karar veremiyorum. Bu sattığımız bir yazılım kütüphanesi değil, bir son kullanıcı uygulamasıdır.

Herhangi bir tavsiye?

İlk yaklaşım için bazı profesyoneller şunlar olabilir:

  • ÖPÜCÜK - her şey çok somut. API, ancak uygulama.
  • güçlü yazılan dönüş değerleri.
  • bu sınıftan miras kalmayacak bir şey yoktur. Hiçbir şey geçersiz kılınamaz, sadece eklenebilir.
  • API çok kapalı, hiçbir şey girmiyor, hiçbir şey geçersiz kılınamıyor, bu yüzden daha az yanlış gidebilir.

Bazı con's:

  • Her yeni hesaplama listeye eklendiğinde, alıcı sayısı artacaktır
  • API'nın değişme olasılığı daha yüksektir ve son değişikliklerin getirilmesi durumunda yeni bir API sürümüne, Foot2'ye ihtiyacımız vardır.
  • sınıfın başka projelerde tekrar kullanılması durumunda her hesaplamaya ihtiyacımız olmayabilir

İkinci yaklaşım için bazı profesyoneller:

  • daha esnek
  • API'nin değişme olasılığı daha düşüktür (soyutlamayı doğru yaptığımızı varsayarsak, değiştirmenin maliyeti daha yüksektir)

Bazı con's:

  • gevşek yazmış. Her çağrıda alınıyor.
  • dize parametresi - Bu konuda kötü duygular var (dize değerlerinde dallanma ...)
  • Ekstra esnekliği zorunlu kılan mevcut kullanım durumu / gereksinimi yoktur, ancak gelecekte olabilir.
  • API kısıtlamalar getirir: her hesaplamanın bir temel sınıftan türetilmesi gerekir. Bu 1 yöntemle bir hesaplama yapmak zorlanacak ve karmaşıklığı daha da artıran parametreleri daha dinamik, süper esnek bir şekilde tasarlamadığımız sürece ekstra parametrelerin geçirilmesi imkansız olacaktır.

5
Bir değer oluşturabilir enumve değerlerini açabilirsiniz . Yine de, ikinci seçeneğin kötü olduğunu düşünüyorum, çünkü KISS'ten sapıyor.
Vorac

Tetiklemek için bir dize parametresi kullanırsanız belirli bir hesaplamanın tüm kullanımlarını bulmak daha zordur. % 100 olmak zor hepsini buldunuz.
Konrad Morawski

İki dünyanın en iyisini alın ve bir avuç dolusu alıcıyla bir cephe yazın getCalculation().
nalply

1
Numaralamalar kesinlikle dizelerden daha iyidir! Bunu düşünmemiştim. API kısıtlamak ve dize parametresinin kötüye kullanımını önlemek (belirteçler ve diğer bok gibi) Bu yüzden karşılaştırma yerine seçenek 1 ve seçenek 2 dize yerine enum arasında olduğunu.
Bgie

Yanıtlar:


6

İlk yaklaşımda işe yarayacağını düşünüyorum. Sihirli dizeler aşağıdaki sorunları oluşturabilir: Yazma hataları, yanlış kullanım, önemsiz olmayan dönüş tipi güvenlik, kod tamamlanma eksikliği, net olmayan kod (bu sürümde bu özellik var mıydı? Sanırım çalışma zamanında bulacağız). Numaralandırma kullanmak bu sorunlardan bazılarını çözecektir, ancak ortaya koyduğunuz eksileri inceleyelim:

  • Her yeni hesaplama listeye eklendiğinde, alıcı sayısı artacaktır

Doğru, bu can sıkıcı olabilir, ancak işleri güzel ve sıkı tutar ve herhangi bir modern IDE'de projenizin herhangi bir yerinde kod tamamlama sağlar, numaralandırmalardan çok daha yararlı olan iyi başlık yorumlarıyla.

  • API'nın değişme olasılığı daha yüksektir ve son değişikliklerin getirilmesi durumunda yeni bir API sürümüne, Foot2'ye ihtiyacımız vardır.

Doğru, ama bu aslında büyük bir profesyonel;) kısmi API'ler için arayüzler tanımlayabilirsiniz ve daha sonra yeni API'lardan etkilenmeyen bağımlı sınıfı yeniden derlemenize gerek yoktur (Yani Foot2'ye gerek yoktur). Bu daha iyi ayrıştırmaya izin verir, bağımlılık artık uygulama değil arayüzdür. Dahası, mevcut bir arayüz değişirse, bağımlı sınıflarda derleme hatası alırsınız;

  • sınıfın başka projelerde tekrar kullanılması durumunda her hesaplamaya ihtiyacımız olmayabilir

Sihirli dizeleri veya numaralandırmaları kullanmanın bu konuda nasıl yardımcı olacağını görmüyorum ... Doğru anlarsam, ya Foot sınıfına kodu eklersiniz ya da birkaç küçük sınıfa ayırırsınız ve bu her iki seçenek için de geçerlidir


Kısmi API'lerin arayüzlerle ilgili fikrini seviyorum, geleceğe dönük görünüyor. Ben onunla gideceğim. Teşekkür ederim. Çok karmaşık hale gelirse (çok fazla arayüz uygulayan ayak), birkaç küçük adaptör sınıfı kullanmak daha esnek olacaktır: Farklı api'ler (ayak, insan ayağı, köpek ayağı, insan ayağıVersion2 gibi) ile birkaç ayak varyasyonu varsa, küçük bir adaptör olabilir. Her biri için bir GUI widget'ının
hepsiyle

Komut seçici kullanmanın bir avantajı, arayüzle birlikte sağlanan statik bir yardımcı yöntem çağrısı anlamadığı bir komutu alan bir uygulamaya sahip olabilmesidir. Komut, genel amaçlı bir yaklaşım kullanılarak neredeyse tüm uygulamalarla yapılabilecek, ancak bazı uygulamaların daha iyi yollarla yapabileceği bir şeyi temsil ediyorsa [örneğin IEnumerable<T>.Count, düşünün ], böyle bir yaklaşım, kodun yeni performans performanslarından yararlanmasına izin verebilir bunları destekleyen ancak eski uygulamalarla uyumlu kalan uygulamaları kullanırken arayüz özellikleri.
supercat

12

Seçenek 3'ü tavsiye ederim: Hesaplamaların a'nın soyutlamasının gerçek bir parçası olmadığını Foot, ancak üzerinde çalıştığını açıkça belirtin . Ardından Footve hesaplamaları şu gibi ayrı sınıflara ayırabilirsiniz:

class Foot : public RecognizedObject {
public:
    // Rather low-level API to access all characteristics that might be needed by a calculation
};

class MaxPressureFrame {
public:
    MaxPressureFrame(const Foot& aFoot); // Performs the calculation based on the information in aFoot
    //API for accessing the results of the calculation
};

// Similar classes for other calculations

Bu şekilde, hesaplamanıza hala güçlü bir şekilde yazabilirsiniz ve mevcut kodu etkilemeden yenilerini ekleyebilirsiniz (maruz kalan miktar bilgisinde ciddi bir hata yapmadıysanız Foot).


Seçenek 1 ve 2'den kesinlikle daha güzel. Bu, strateji tasarım modelini kullanmaktan sadece kısa bir adım uzaklıktadır.
Brian

4
Bu uygun olabilir. Bu aşırı olabilir. Hesaplamaların ne kadar karmaşık olduğuna bağlıdır. Bir MaxPressureFrameStrategy ve MaxPressureFrameStrategyFactory ekleyecek misiniz? Ve Ayağı Anemik Nesneye çevirme eğilimindedir.
user949300

Bu güzel bir alternatif olsa da, bağımlılıkları tersine çevirmek bizim durumumuzda işe yaramaz. Ayak da bir tür arabulucu olarak hareket etmelidir, çünkü başka bir hesap değiştiğinde bazı hesaplamalar yeniden hesaplanmalıdır (kullanıcının bir parametreyi değiştirmesi nedeniyle).
Bgie

@Bgie: Hesaplamalar arasındaki bu tür bağımlılıklar ile, @ user116462 ile ilk seçeneğin en iyisi olduğuna katılıyorum. ”
Bart van Ingen Schenau
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.