Kullanıcı bilgilerini görüntüleyen alıcılardan ve ayarlayıcılardan kaçının


10

Arka fon

Ben "Temiz Kod kitap" okuyorum ve paralel olarak, bankacı hesabı gibi Kata jimnastik nesneleri üzerinde çalışıyorum ve bu kural üzerinde sıkışıp kaldım:

Jimnastik nesnelerinin 9. kuralı, alıcı veya ayarlayıcı kullanmamamızdır.

Oldukça eğlenceli görünüyor ve bu prensibe katılıyorum. Dahası, Temiz Kod'un 98-99. Sayfalarında yazar, getters / setters'ın soyutlamayı kırdığını ve nesnemize sormamız gerekmediğini, ancak nesnemize söylememiz gerektiğini açıklar.

Bu aklıma mükemmel geliyor ve bu prensibe tamamen katılıyorum. Sorun pratikte ortaya çıkıyor.

bağlam

Örneğin, bazı kullanıcıları listelemem ve kullanıcı ayrıntılarını görüntülemem gereken bir uygulamam var.

Kullanıcım şunlardan oluşur:

-> Name
   --> Firstname --> String
   --> Lastname --> String
-> PostalAddress
   --> Street --> String
   --> PostalCode --> String

Sorun

Yalnızca basit bir bilgi görüntülemem gerektiğinde ( ve o alanda fazladan işleme ihtiyacım olmadığını doğrulamam gerekir) alıcıları önlemek için ne yapabilirim ya da basit bir ad ( rastgele) çıkış desteği?

Aklımda ne var

Bir çözüm yapmak:

user.getName().getFirstName().getStringValue()

Tamamen korkunç olan, jimnastik nesnelerinin birçok kuralını çiğneyen ve Demeter Yasasını çiğneyen.

Bir diğeri şöyle bir şey olurdu:

String firstName = user.provideFirstnameForOutput();
// That would have called in the user object =>
String firstName = name.provideFirstnameForOutput();
// That would have called in the name object =>
String firstName = firstname.provideFirstnameForOutput();

Ama bu çözümden çok rahat hissetmiyorum, sadece standart bir alıcı / ayarlayıcıyı sadece Demeter yasalarını eşleştirmeyi amaçlayan bir yöntemle atlamak gibi bir "daha üst düzey erişimci" gibi görünüyor ...

Herhangi bir fikir ?

Yanıtlar:


17

Alıcılardan ve ayarlayıcılardan kaçınma fikri hakkındaki yaygın yanlış anlama, her yerde onlardan kaçınmaktır.

Nesnelerin bağlam sağlayan toplamalar kullanılarak korunması ve yöntemlerin komut olarak hareket etmesi gereken, uygulamanızın business-logic bölümünde alıcıları ve ayarlayıcıları kullanmaktan kaçınmalısınız.

Alıcıları ve ayarlayıcıları önlemek için, reaktif programlamaya benzer bir çözüm tasarlayabilir , gözlemlenebilir varlıklar aracılığıyla raporlama sistemi uygulayabilirsiniz, ancak bu tasarım kullanıcı arayüzleri için gerçekten iyi olmasına rağmen, mimariyi son derece karmaşıklaştırır ve uygulamanızın CRUD düzeyinde bir anlam ifade etmez.

Alıcıları / ayarlayıcıları kullanmayı düşünüp düşünmemeniz tamamen uygulamanın çalışmakta olduğunuz kısmına bağlıdır. Endişeniz getters kullanan kullanıcı arayüzü tamamen iyi ise, iş mantığı için, bir alıcıdan alınan bir değere dayanan bir kod parçasını o kadar çok çalıştırmayacaksanız (bu mantığın aslında içinde kapsüllenmiş olması gerektiğini bağırır) alıcıyı aradığınız sınıf).

Ayrıca, demeter yasası noktaları saymakla ilgili değildir, sadece kendi başına erişmemeniz gereken bileşenlerini elde etmek için sınıftaki alıcıları kullanarak bağlam sağlayan bir sınıfı ayırmakla ilgilidir.

Kullanıcı arayüzünüzün iş modellerinizde çok derinleştiğini düşünüyorsanız, modellerin belirli bölümlerini görsel temsillere dönüştürmekten sorumlu olan sisteminize görünüm modellerini tanıtmayı düşünebilirsiniz.


Tamam, sanırım bu öneri, alan adı varlığım arasındaki bir eşleyici gibi, sunum katmanım için bazı erişimcilere sahip olacak özel bir DTO'ya doğru mu?
mfrachet

@Margin Hemen hemen evet.
Andy

Tüm bu basamaklı şeyler gerçekten iyi ve pürüzsüz geliyor, cevap için teşekkürler;)
mfrachet

2

Düşünülmesi gereken bir yön, ham verilere erişim sağlamak yerine genel bir dize biçimlendirme üyesi işlevi sağlamak olacaktır. Bunun gibi bir şey:

String lastName = user.formatDescription("$(Lastname)");
String fullName = user.formatDescription("$(Lastname), $(Firstname)");
String abbreviated = user.formatDescription("$(FnAbb). $(LnAbb).");

Görüyorsunuz, bu yaklaşımla, sadece tam verileri olduğu gibi sunmakla sınırlı değilsiniz, verileri uygun ve anlamlı yollarla dönüştürmek için araçlar sağlayabilirsiniz. Örneğin, karakter durumuyla hileler oynamanız gerekebilir:

String accountName = user.formatDescription("$(firstname).$(lastname)");

Ayrıca, sık kullanılan bazı karmaşık biçimleri bir kez tanımlayabilirsiniz. Örneğin,

String fullAddress = user.formatDescription(User.kAddressFormat);

Bu yaklaşımın güzelliği, bireysel Userkodları sınıfın içinde tutarken, aslında çağrı koduna çok daha fazla işlevsellik sağlamasıdır. Bununla birlikte, dezavantajı, içinde formatDescription()birkaç kod satırı olacak şablonlama mekanizmasını uygulamanız gerektiğidir .

Bu nedenle, bu tamamen aşırı olabilir: Programlama prensiplerinin sadece rehber olduğunu unutmayın. Ve başka bir prensibi takip etmek KISS prensibini ihlal ediyorsa, muhtemelen bunu basit bir şekilde yapmak en iyisidir. Bu nedenle, en azından böyle bir biçimlendirme üyesine ihtiyacınız olmadığı sürece, erişimci tabanlı yaklaşımı kullanarak basitlik adına uygulamayı zahmete sokmam.


5
Ancak bu benim için bir SRP ihlali gibi görünüyor. UserŞablon bir dili ayrıştırmak ve derlemek / yorumlamak gerçekten bir nesnenin sorumluluğu mudur ?
Jörg W Mittag

@ JörgWMittag Mutlaka olması gerekmez. Dediğim gibi, KISS ilkesi öncelik kazanıyor. Ve hiçbir yerde Usersınıfın bu işlevselliğin kendisini uygulaması gerektiğini söylemedim . Eğer böyle bir işlevselliğe ihtiyacı olan sadece iki sınıfım olsaydı, şablon değiştirme mekanizmasını kendi sınıfına dahil ederek bana bahse girebilirsin. Bu, Useraslında bir veri kabından daha fazlası olduğu bir seviyeye ulaşan soyutlamayı nasıl kaldırabileceğinize bir örnek olması içindir . Ve inanıyorum ki, erişimcilerden kaçınmak tamamen bununla ilgilidir: bir sürü structs yerine OOP yapmak .
cmaster - eski haline monica

KISS'in tamamen öznel ve SRP objektif olduğunu biliyor musunuz? KISS size ne yapmanız gerektiği hakkında bir şey söylemiyor. Ve sizin için "Basit" olan şey benim için "basit" olmayabilir. KISS veya SRP ile tartışırken kalite konusunda gerçek bir fark görüyorum.
oopexpert
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.