Kendini referans alan yöntem zincirlemesinin gerçek dezavantajları var mı?


14

Son zamanlarda belirli bir projede belirli bir sınıf için zincirleme yönteminin uygulanmasını önerdim, böylece kodun okunabilirliği geliştirilebilir. Sadece kolaylık sağlamak için değil, anlambilim için de akıcı arayüzler uygulanmalı ve benim önerim reddedildi. Akıcı bir arayüz önermediğimi ama okunabilirliği ve kodlama konforunu iyileştirmek için kendini zincirleme yönteminin (her ikisi de birbiriyle karıştırılabilir , alt kısımda okunabilir) yanıt verdiğimde , öneri tekrar vuruldu.

Her neyse, bu beni her zaman bir şey döndürmesi gerekmeyen yöntemlerde (örneğin ayarlayıcılar) "bu" yı döndürerek kötü bir uygulamada olabileceğimi düşündürdü.

Sorum şu: önceki sözleşmeyi uygulamak kötü uygulama veya istismar olarak kabul edilebilir mi? Performansın bir dezavantajı olduğunu düşünmüyorum ya da var mı?



@KeesDijk Teşekkürler, aynı sınıftan zincirleme yöntemleri konusunda daha fazla ilgilendiğim için, bu soruna benzer değil, sorumu biraz düzenledim
dukeofgaming

1
SO'da, zincirlemenin C ++ için olmadığını söylediler - stackoverflow.com/questions/5760551/… - ne düşünüyorsun?
kagali-san

1
mhambra Görünüşe göre sadece yöntem zinciri uygularken dikkatli olmanız ve bunun için açık standartlar tanımlamanız gerekir.
dukeofgaming

Yanıtlar:


10

Hayır

Kent Beck'in belirttiği gibi , kod yazıldığından çok daha sık okunur.

Yöntem zinciri kodunuzu daha okunaklı hale getirirse yöntem zincirlemeyi kullanın.


1
Harika kitap .. +1
Rein Henrichs

5
ANCAK , daha okunaklı bir zincirleme metoduysanız ne olacak? Bu sistematik bir sorunsa, tutarlılık için bir dizi kodlama kuralına bağlı kalacaksınız: bu, tutarlılık için mevcut kodla aynı şekilde yazmak anlamına gelir.
coredump

OP zaten bunu söylenenlerekörü gibi geliyor @coredump ama Steven sadece bu hitap ettiğini düşünüyorum eğer yöntem zincirleme daha okunabilir hale getirir.
Panzercrisis

1
@Panzercrisis OP'lerin kolaylık ve anlambilim nedeniyle yöntem zincirleme kullanarak kaçınmaları söylendi. Steven'ın cevabı temel olarak "yine de yap" der ve takımın görüşünü veya tutarlılığını dikkate almadan OP kodunun sadece okunabilirliğini düşünün. OP, kodun okunabilirliği konusundaki zevkine uyması için projedeki mevcut her sınıfı yeniden yazmak isterse ne olur? Kolaylık / anlambilim argümanını şu şekilde anlıyorum: yöntem zincirleme yapmak için "teknik" bir neden olmalı (btw, bu argüman aynı zamanda diğer kişi kendi tercihleri ​​için bir bahane
uyduruyor gibi geliyor

9

Evet, sakıncaları var

Okunması kolay kod iyidir, ancak kodun ne iletişim kurduğuna da dikkat edin . Bir nesnenin yöntemleri her zaman nesneyi döndürdüğünde, birkaç şey iletir:

  1. Hangi şeylerin ayarlanması veya yapılandırılması gerektiği açıkça belli olmayan gelişmiş yapılandırmaya ihtiyacım var
  2. Her bir sonraki yöntem çağrısı son

Geçerli Kullanım Durumu: Geçici Veritabanı Sorguları

Sınıf kütüphaneleri, sabit kodlu SQL'e başvurmadan bir veritabanını sorgulamanızı sağlayan her dilde bulunur. .NET için Entity Framework'ü örnek olarak alalım:

DBContext db = new DBContext();
List<Post> posts = db.Posts
    .Where(post => post.Title.Contains("Test"))
    .OrderBy(post => post.DateCreated)
    .ToList();

Bu, her bir sonraki yöntem çağrısının bir öncekine dayandığı akıcı bir arayüzdür. Bu çağrıları mantıksal olarak okumak, bir veritabanını sorgulama bağlamında anlamlıdır.

Geçersiz Kullanım Durumu: Ayar Özellikleri İçin Sözdizimsel Şeker

Şimdi Postsınıfla aynı modeli kullanalım :

public class Post
{
    public string Title { get; set; }
    public DateTime DateCreated { get; set; }
    public string Body { get; set; }

    public Post SetTitle(string title)
    {
        Title = title;

        return this;
    }

    public Post SetDateCreated(DateTime created)
    {
        DateCreated = created;

        return this;
    }

    public Post SetBody(string body)
    {
        Body = body;

        return this;
    }
}

Şimdi bu sınıfı nasıl kullanacağınıza bakalım:

Post post = new Post()
    .SetTitle("Test")
    .SetDateCreated(DateTime.Now)
    .SetBody("Just a test");

Bu kodu gördüğümde hemen şu soruyu sorarım: " SetBodyAradıktan sonra veritabanını sorgular mı?" Bitirdim mi? "Demek için başka bir yöntem çağırmam gerekir mi?"

Zincirleme yöntem çağrıları sınıfı kullanarak kodla ne iletişim kurarPost ?

  1. Karmaşık bir kurulumum var
  2. Her yöntem çağrısı bir öncekine dayanır

Bu gerçekten doğru mu? Hayır Postsınıf yok değil bir karmaşık kurulum var. Başlık, oluşturulma tarihi ve gövde ayarlanması, daha karmaşık bir nihai hedefe yönelik olarak birbirini etkilemez . Yuvarlak bir deliğe kare bir pimi ezdiniz.

Kendine başvurulan yöntem zincirlemesinin dezavantajı, bir şey yapmak için birden çok yöntem çağrısının gerekli olduğunu ve her çağrının sonuncuyu oluşturduğunu bildirmenizdir. Bu doğru değilse, yöntem zincirleme yanlış şeyi diğer programcılara iletiyor olabilir.

İş arkadaşlarınız dediğinde:

Akıcı arayüzler sadece kolaylık sağlamak için değil, anlambilim için de uygulanmalıdır.

Kesinlikle doğruydu. Akıcı bir arayüz veya yöntem zinciri, kendi başına doğru olmayan bir şey iletir.


Bu yöntem zincirleme ve karmaşık konfigürasyonun her zaman el ele gittiğini varsayar. Onlar farklı varlıklardır ve birinin varlığı sizi diğerini varsaymaya zorlamamalıdır.
Jack,

Bu sadece "karmaşık yapılandırma" değil, aynı zamanda "öncekini oluşturan sonraki yöntem çağrılarıdır". Metot zincirlemenin, bir sınıfın amacı için her zaman doğru olmayan bir meta iletişimi vardır.
Greg Burghardt

1
Müteakip yöntem çağrıları öncekilerden inşası da yöntem zincirlemesinden farklıdır ve yöntem zincirleme sözdiziminin, sıraya bağlı yan etki operasyonları serisi anlambilimi için güçlü bir iletişim olarak ele alınmasının güvenilir veya yararlı olduğunu düşünmüyorum. Sözdizimsel bir steno, başka bir şey değil. İşleri daha kısa ve daha okunabilir hale getirdiği yerlerde kullanın.
Jack

1
Sana yöntem zincirleme ayrı olduğunu düşünüyorum anlıyorum ama söylüyorum o kafanın içinde değildi ve diğer sınıf kitaplıkları kullanan diğer programcılar do yanlış olan Kodunuzdaki varsayımlara bitebileceğini Bu nedenlerle yöntem zincirleme uygulamak. Yöntem zincirlemenin, kod yazarı olarak sizin istemediğiniz bir şeyi ima edebileceğini unutmayın. Açık bir şekilde iletişim kuran kod, okunması kolay kod kadar önemlidir. Birini diğeri için feda etme.
Greg Burghardt

1
When an object's methods always return the object, it communicates a couple of things- Bence bu kişisel bir görüş; zincirleme yöntemlere bakan herkesin aynı şeyleri üstleneceğini iddia etmek zor.
Sam Dufel

1

Ana dezavantajı netlik kaybıdır. Örneğin:

x.foo();
x.bar();
x.baz();

Bu ifadelerin hiçbiri bir değer döndürmediği için (ya da varsa, yok sayılır), yalnızca yan etki üretiyorlarsa yararlı olabilirler. Şununla karşılaştır:

x.foo()
 .bar()
 .baz();

Birincisi, sınıfının bu yöntemlere sahip tek sınıf olduğunu bilmiyorsanız, açık değildir barve bazaynı türdeki nesneler üzerinde çalışır . Durum böyle olsa bile, yöntemlerin veya yeni nesnelerin çalıştığı açık değildir .xxx

Kodun yan etkileri olan bölümlerini vurgulamak yararlıdır, çünkü bu yan etkileri programla ilgili akıl yürütmek için izlemeniz gerekir. Kod yazma kolaylığı açısından potansiyel kazanç karşısında potansiyel netlik kaybını tartmak zorundasınız, ancak kodun yazıldığından daha fazla okunduğunu da düşünmelisiniz.


0

Programlama dillerinin tüm stilistik unsurlarını düşünün (el kodlama makinesi dilinin aksine) ve "anlambilim kolaylık değil" argümanını zayıflatır.

Mühendis olarak yaptığımız işlerin çoğu anlambilim konusunda kolaylık sağlamaktır.

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.