Temiz kod: birkaç parametreyle kısa yöntemlerin sonuçları


15

Son zamanlarda bir kod incelemesi sırasında, kokulu bir desen içeren yeni bir meslektaşım tarafından yazılmış bir kodla karşılaştım. Meslektaşımın kararlarının ünlü Temiz Kod kitabı (ve belki de diğer benzer kitaplar) tarafından önerilen kurallara dayandığından şüpheleniyorum.

Sınıf kurucusunun geçerli bir nesnenin yaratılmasından tamamen sorumlu olduğunu ve ana görevinin bir nesnenin (özel) özelliklerinin atanması olduğunu anlıyorum. Elbette isteğe bağlı özellik değerlerinin sınıf yapıcısı dışındaki yöntemlerle ayarlanabileceği ortaya çıkabilir, ancak bu tür durumlar oldukça nadirdir (sınıfın geri kalanının böyle bir özelliğin seçeneğini dikkate alması şartıyla mutlaka yanlış olmasa da). Bu önemlidir, çünkü nesnenin her zaman geçerli bir durumda olmasını sağlar.

Ancak, karşılaştığım kodda, çoğu özellik değerleri aslında yapıcı dışında başka yöntemler tarafından ayarlanır. Hesaplamalardan kaynaklanan değerler, sınıf boyunca birkaç özel yöntemde kullanılacak özelliklere atanır. Yazar görünüşte sınıf özelliklerini, bu değerleri gereksinim duyan işlevlere parametreleştirmek yerine sınıf boyunca erişilebilir olması gereken küresel değişkenler gibi kullanıyor. Ayrıca, sınıfın yöntemleri belirli bir sırayla çağrılmalıdır, çünkü sınıf başka bir şey yapmaz.

Bu kodun büyük parametre listelerinden (<3 parametre) kaçınmak için yöntemleri kısa tutma (<= 5 satır kod) tavsiyesinden esinlendiğinden ve yapıcıların (bir çeşit hesaplama yapmak gibi) çalışmaması gerektiğinden şüpheleniyorum nesnenin geçerliliği için gereklidir).

Tabii ki, yöntemler belirli bir sırayla çağrılmadığında her türlü tanımlanmamış hatanın potansiyel olarak ortaya çıkabileceğini kanıtlayabilirsem, şimdi bu kalıba karşı bir dava yapabilirim. Ancak, buna yanıtın, bu özelliklerin ayarlanması gereken yöntemler çağrıldıktan sonra özelliklerin ayarlanması gerektiğini doğrulayan doğrulamalar ekleyeceğini tahmin ediyorum.

Bununla birlikte, sınıfın (yordamsal olarak) belirli bir sırayla çağrılması gereken bir dizi yöntem yerine, gerçek bir nesneye mavi bir baskı haline gelmesi için kodu tamamen değiştirmeyi öneriyorum.

Karşılaştığım kodun koktuğunu hissediyorum. Aslında, ne zaman bir sınıf özelliğinde bir değer kaydetmek ve ne zaman kullanmak için farklı bir yöntem için bir parametreye koymak için oldukça açık bir ayrım var inanıyorum - gerçekten birbirlerine alternatif olabilir inanmıyorum . Bu ayrımın kelimelerini arıyorum.


6
1. Bir an için şeytanın avukatı oynuyor ... Kod gerçekten işe yarıyor mu? Çünkü Veri Aktarımı Nesneleri mükemmel derecede geçerli bir tekniktir ve eğer hepsi bu ise ...
Robert Harvey

7
2. Sorunu tanımlayacak kelimeleriniz yoksa, iş arkadaşınızın konumunu çürütmek için yeterli deneyime sahip değilsiniz.
Robert Harvey

4
3. Yayınlayabileceğiniz bazı çalışma kodlarınız varsa, Kod İncelemesine gönderin ve onlara bir göz atmalarını sağlayın. Aksi takdirde, bu sadece dolaşan bir genelliktir.
Robert Harvey

5
@RobertHarvey "Hesaplamalar sonucunda ortaya çıkan değerler, sınıf boyunca çeşitli özel yöntemlerde kullanılacak özelliklere atanır" benim için kendine saygılı bir DTO gibi gelmez. Biraz daha özgüllüğün faydalı olacağını kabul ediyorum.
topo Monica'yı eski haline getirin

4
Bir kenara: Birisi, kodlamadan önce aslında Temiz Kod okumamış gibi görünüyor. Tekrar taradım ve "inşaatçılar iş yapmamalı" diye bir yer bulamadım (aslında bazı örnekler iş yapıyor) ve çok fazla parametreden kaçınmak için önerilen çözüm, ilgili birleştirme nesnesi oluşturmaktır. parametre grupları, işlevlerinizi pusuya düşürmeyin. Ve kitap , yöntemler arasındaki zamansal bağımlılıkları önlemek için kodu yeniden düzenleme önermektedir. Bence onun tercih ettiği kod stillerinden birkaçına karşı önyargınız kitabı algılamanızı renklendirdi.
Eric King

Yanıtlar:


13

Clean Code'u okuyan ve Clean Coders serisini izleyen biri, birden çok kez ve sık sık diğer kişilere daha temiz kod yazmayı öğretip koçluk yaptığı için, gerçekten gözlemlerinizin doğru olduğunu kefil edebilirim - işaret ettiğiniz metriklerin hepsi kitapta belirtilmiştir .

Ancak kitap, belirttiğiniz yönergelerin yanında da uygulanması gereken diğer hususları ele almaya devam ediyor. Bunlar, ele aldığınız kodda göz ardı edildi. Bu olmuş olabilir, çünkü meslektaşınız hala öğrenme aşamasındadır, bu durumda, kodlarının kokularını belirtmek gerektiği kadar , bunu iyi niyetle, öğrenme ve denediklerini hatırlamak iyidir. daha iyi kod yazmak için.

Temiz Kod, yöntemlerin mümkün olduğunca az argümanla kısa olması gerektiğini önermektedir. Ancak bu yönergeler boyunca, S OLID ilkelerini izlememiz, uyumu artırmamız ve kuplajı azaltmamız gerektiğini önermektedir .

S Tek Sorumluluk İlkesi için KATI tribünlerde bir nesne tek bir şey sorumlu olması gerektiğini hangi devletler. "Şey" çok kesin bir terim değildir, bu nedenle bu ilkenin açıklamaları çılgınca değişir. Bununla birlikte, Temiz Kod'un yazarı Bob Amca, aynı zamanda bu ilkeyi belirleyen kişidir: "Aynı nedenlerle değişen şeyleri bir araya getirin. Farklı nedenlerle değişen şeyleri ayırın." Burada ve burada değişmek için nedenlerle ne demek istediğini söylemeye devam ediyor(burada daha uzun bir açıklama çok fazla olur). Bu ilke, uğraştığınız sınıfa uygulanmışsa, hesaplamaların üstesinden gelen parçaların, kaç nedenden dolayı sınıfı ikiye veya daha fazlasına bölerek tutma durumu ile ilgili olanlardan ayrılması muhtemeldir. bu hesaplamaları değiştirmek için var.

Ayrıca, Temiz sınıflar uyumlu olmalıdır , yani yöntemlerinin çoğu özelliklerinin çoğunu kullanır. Bu haliyle, azami derecede uyumlu bir sınıf, bütün yöntemlerin bütün niteliklerini kullandığı sınıftır; örnek olarak, grafiksel bir uygulamada Vector, özniteliklere sahip bir sınıfa sahip olabilirsiniz Point ave Point bburada yalnızca yöntemler vardır scaleBy(double factor)ve printTo(Canvas canvas)her ikisi de her iki nitelikte de çalışır. Buna karşılık, minimal olarak uyumlu bir sınıf, her bir özniteliğin yalnızca bir yöntemde kullanıldığı ve her bir yöntem tarafından asla birden fazla özniteliğin kullanıldığı sınıftır. Yapışkan parçaların ortalama olarak, bir sınıf hediyeler olmayan yapışkan "gruplar" - yani birkaç yöntemler özelliklerini kullanmak a, bve c, dinlenme kullanımı sırasında cved - yani, sınıfı ikiye bölersek, iki birbirine bağlı nesne ile sonuçlanırız.

Son olarak, Temiz sınıflar kuplajı mümkün olduğunca azaltmalıdır . Burada tartışılmaya değer birçok bağlantı türü olsa da, eldeki kodun esas olarak geçici bağlantıdan muzdarip olduğu görülüyor , burada belirttiğiniz gibi, nesnenin yöntemleri sadece doğru sırada çağrıldıklarında beklendiği gibi çalışacaktır. Ve yukarıda belirtilen iki kılavuz gibi, bunun çözümleri genellikle sınıfın iki veya daha fazla uyumlu nesneye bölünmesini içerir . Bu durumda bölme stratejisi genellikle Builder veya Factory gibi desenleri ve oldukça karmaşık durumlarda State-Machines'i içerir.

TL; DR: Meslektaşınızın izlediği Temiz Kod yönergeleri iyidir, ancak aynı zamanda kitapta belirtilen diğer ilke, uygulama ve kalıplara da uyulduğunda. Temiz Birden sınıflara bölünmüş olacağını görüyoruz "sınıf" versiyonu, tek sorumluluk, yapışkan yöntemleri ve hiçbir zamansal kavramalı her. Bu, küçük yöntemlerin ve az ya da hiç tartışmanın mantıklı olduğu bağlamdır.


1
Hem sen hem de topo morto iyi bir cevap yazdınız, ama sadece bir tanesini kabul edebilirim. SRP, bağlılık ve kuplajı ele almanızı seviyorum. Bunlar kod incelemesinde kullanabileceğiniz yararlı terimlerdir. Nesneyi kendi sorumlulukları ile daha küçük nesnelere bölmek elbette gidilecek yoldur. Değerleri bir grup özellik üzerine başlatan bir (yapıcı olmayan) yöntem, yeni bir nesnenin döndürülmesi gereken ölü bir hediyedir. Bunu görmeliydim.
16:16

1
SRP en önemli kılavuzdur; hepsini ve hepsini yönetecek bir yüzük. İyi yapılmış SRP doğal olarak daha kısa yöntemlerle sonuçlanır. Örnek: Sadece 2 ortak ve yaklaşık 8 halka açık olmayan yöntemle öne bakan bir sınıfım var. Hiçbiri ~ 3 satırdan fazla değildir; tüm sınıf 35 LOC civarındadır. Ama bu sınıfı en son yazdım! Altta yatan tüm kod yazıldığında bu sınıf esasen kendini yazdı ve yöntemleri daha büyük yapmak zorunda kalmadım. Hiçbir zaman "Beni öldürürse bu yöntemleri 5 satıra yazacağım" demedim. SRP'yi her uyguladığınızda olur.
radarbob

11

Sınıf kurucusunun geçerli bir nesnenin yaratılmasından tamamen sorumlu olduğunu ve ana görevinin bir nesnenin (özel) özelliklerinin atanması olduğunu anlıyorum.

Genellikle nesneyi ilk geçerli duruma koymaktan sorumludur, evet; diğer özellikler veya yöntemler daha sonra durumu başka bir geçerli duruma değiştirebilir.

Ancak, karşılaştığım kodda, çoğu özellik değerleri aslında yapıcı dışında başka yöntemler tarafından ayarlanır. Hesaplamalardan kaynaklanan değerler, sınıf boyunca birkaç özel yöntemde kullanılacak özelliklere atanır. Yazar görünüşte sınıf özelliklerini, bu değerleri gereksinim duyan işlevlere parametreleştirmek yerine sınıf boyunca erişilebilir olması gereken küresel değişkenler gibi kullanıyor. Ayrıca, sınıfın yöntemleri belirli bir sırayla çağrılmalıdır, çünkü sınıf başka bir şey yapmaz.

Okuduğunuz okunabilirlik ve sürdürülebilirlik sorunlarının yanı sıra, sınıfın kendisinde devam eden birden fazla veri akışı / dönüşümü aşaması var gibi görünüyor, bu da sınıfın tek sorumluluk ilkesine düştüğünü gösterebilir.

büyük kod listelerinden (<3 parametre) kaçınmak için bu kodun yöntemleri kısa tutma (<= 5 satır kod) tavsiyesinden esinlendiğinden ve yapıcıların (örneğin, nesnenin geçerliliği için gereklidir).

Bazı kodlama yönergelerine uymak, diğerlerini görmezden gelmek genellikle aptalca kodlara yol açar. Eğer biz örneğin, işi bir kurucu önlemek istiyorsanız, mantıklı bir yol genellikle inşaat öncesi işi yapmak ve yapıcısına bu işin sonucunu geçmek olacaktır. (Bu yaklaşımın bir argümanı, sınıfınıza iki sorumluluk vermekten kaçınmanız olabilir: başlatma sürecinin çalışması ve 'ana işi', ne olursa olsun.)

Deneyimlerime göre, sınıfları ve yöntemleri küçük yapmak nadiren ayrı bir düşünce olarak akılda tutmam gereken bir şeydir - daha ziyade, doğal olarak tek sorumluluktan kaynaklanmaktadır.

Bununla birlikte, sınıfın (yordamsal olarak) belirli bir sırayla çağrılması gereken bir dizi yöntem yerine, gerçek bir nesneye mavi bir baskı haline gelmesi için kodu tamamen değiştirmeyi öneriyorum.

Muhtemelen bunu yapmak doğru olur. Basit prosedür kodu yazmanın yanlış bir yanı yoktur; gizlenmiş prosedürel kod yazmak için OO paradigmasının kötüye kullanılmasında bir sorun var.

Ne zaman bir sınıf özelliği bir değer kaydetmek ve ne zaman kullanmak için farklı bir yöntem için bir parametreye koymak için oldukça açık bir ayrım var inanıyorum - gerçekten onlar birbirlerine alternatif olabilir inanmıyorum. Bu ayrımın kelimelerini arıyorum.

Genellikle , bir alana bir değeri bir yöntemden diğerine geçirmenin bir yolu olarak koymamalısınız; bir alandaki bir değer, belirli bir zamanda bir nesnenin durumunun anlamlı bir parçası olmalıdır. (Bazı geçerli istisnaları düşünebilirim, ancak bu tür yöntemlerin halka açık olduğu veya sınıftaki bir kullanıcının farkında olması gereken bir emir bağımlılığının olduğu durumlar değil)


2
çünkü: 1. SRP'yi vurgulamak. "... küçük yöntemler ... doğal olarak takip et" 2. Yapıcı amacı - geçerli durum. 3. "Diğerlerini yok sayarken bazı kodlama yönergelerine uymak." Bu kodlamanın Yürüyen Ölüleridir.
radarbob

6

Büyük olasılıkla burada yanlış desene karşı korkuluk yapıyorsunuz. Küçük fonksiyonlar ve düşük aritite kendi başlarına nadiren problemlidir. Asıl mesele burada, fonksiyonlar arasında sipariş bağımlılığa yol kavrama yani bu adrese yollarını bakmak olmadan küçük etkinlikler faydalarını atmadan.

Kod kelimelerden daha yüksek sesle konuşur. Yeniden düzenleme işleminin bir kısmını yapabilir ve iyileştirmeyi belki bir çift programlama alıştırması olarak gösterebilirseniz, insanlar bu tür düzeltmeleri çok daha iyi alırlar. Bunu yaptığımda, tüm kriterleri dengeleyerek tasarımı doğru bulmayı düşündüğümden daha zor olduğunu düşünüyorum .

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.