“Erken soyutlama” nedir?


10

Cümlenin etrafına atıldığını duydum ve bana argümanlar tamamen çılgınca geliyor (burada samanlık çekiyorsam özür dilerim, Niyetim değil), genellikle şu satırlarda bir şeyler gider:

Genel davanın ne olduğunu bilmeden soyutlama yapmak istemezsiniz, aksi takdirde (1) soyutlamalarınıza ait olmayan şeyleri koyuyor veya (2) önemli şeyleri atlıyor olabilirsiniz.

(1) Bana göre bu programcı yeterince pragmatik değil gibi, son programda olmayan şeylerin var olacağı varsayımlarında bulundular, bu yüzden düşük düzeyde bir soyutlama ile çalışıyorlar, sorun değil erken soyutlama, bu erken betonlaşmadır.

(2) Önemli şeyleri atlamak bir şeydir, daha sonra önemli olduğu ortaya çıkan spesifikasyondan tamamen bir şey atlanabilir, bunun çözümü sizi bulduğunuzda kendi betonunuzu ve atık kaynaklarınızı ortaya çıkarmak değildir. yanlış tahmin, istemciden daha fazla bilgi almak için.

Her zaman soyutlamalardan betonlara kadar çalışmalıyız, çünkü bu bir şeyleri yapmanın en pragmatik yolu, tersi değil.

Bunu yapmazsak, müşterileri yanlış anlama ve değiştirilmesi gereken şeyler yaratma riskiyle karşı karşıya kalırız, ancak sadece müşterilerin kendi dillerinde tanımladıkları soyutlamaları yaparsak, bu riske asla ulaşmayız (en azından hiçbir şekilde karanlıkta bazı somutluklarla bir çekim), evet müşteriler ayrıntılarla ilgili fikirlerini değiştirebilirler, ancak aslında istediklerini iletmek için kullandıkları soyutlamalar hala geçerli olma eğilimindedir.

İşte bir örnek, bir müşterinin bir ürün torbalama robotu oluşturmanızı istediğini varsayalım:

public abstract class BaggingRobot() {
    private Collection<Item> items;

    public abstract void bag(Item item);
}

Müşterinin bilmediğimiz şeylerle daha fazla ayrıntıya girmeden kullandığı soyutlamalardan bir şeyler inşa ediyoruz. Bu son derece esnektir, gerçekte torbalamanın nasıl uygulandığını varsaymak daha erken olurken, "erken soyutlama" olarak adlandırıldığını gördüm. . Sınıfımı güncellemek için tek ihtiyacım olan imzayı değiştirmek, ancak aşağıdan yukarıya başlayan biri için büyük bir sistem revizyonu gerektirebilir.

Erken soyutlama diye bir şey yoktur, sadece erken somutlaşma vardır. Bu bildiride yanlış olan ne? Akıl yürütmemdeki kusurlar nerede? Teşekkürler.


1
Erken soyutlamanın tersi YAGNI - Bana göre neredeyse her zaman yanlış olan İhtiyacınız Yok. Neredeyse. Bunun olduğunu gördüm, ama nadir. Burada söylediklerinize katılıyorum.
user1118321

Yanıtlar:


19

En azından benim görüşüme göre, erken soyutlama oldukça yaygındır ve özellikle OOP tarihinde çok erken olmuştur.

En azından gördüğüm kadarıyla ortaya çıkan en büyük sorun, insanların nesne yönelimli hiyerarşilerin tipik örneklerini okumasıydı. Onlar gelecek değişikliklerle başa her şeyi hazır hale çok bahsetti var olabilir (onlar olur inanmak için hiçbir özellikle iyi bir nedeni olduğunu bile) ortaya çıkar. Bir süre birçok makalede ortak olan bir diğer tema, "memelilerin hepsi böyle" veya "kuşların hepsi böyle" ile ilgili basit kurallara meydan okuyan platypus gibi şeylerdi.

Sonuç olarak, sadece çalışanların kayıtlarıyla uğraşmak için gerçekten gerekli olan, ancak bir araknid veya belki de bir kabuklular kiraladıysanız, hazır olmak için dikkatli bir şekilde yazılan bir kodla sona erdik.


Dolayısıyla, erken soyutlama soyutlama eylemi değil, soyutlama seviyesinin ötesinde soyutlama eylemidir. Bu çok daha mantıklı ve aslında bunun olduğunu görebiliyordum. Sanırım sadece yöneticim tarafından özetlenen soyutlama seviyesinde çalıştığımı meslektaşlarıma daha açık hale getirmem gerekiyor.
James

1
@James: daha sonraki bir sürümün spesifikasyonunda yeni bir gereksinim bildiğinize inandığınızdan, sürüm 1.0'ın teknik özelliklerinden "çok fazla" soyutlamak anlamına gelebilir, bu nedenle zaten v1.0'ı daha genel bir şekilde uygular gerekli. Bazı şeyler, daha sonraki bir versiyonda neler olabileceğini öngörmek iyidir, ancak belirli bir aşırı mühendislik riski de vardır.
Doc Brown

@DocBrown Ben bu erken betonlama derdim. Soyutlama eylemi, bilgi parçalarını kaldırmaktır, onları eklemektir. Soyutlamaya gerekenden daha fazlasını ekliyorsanız, daha düşük soyutlama seviyeleri hakkında bir şey varsayıyorsunuz demektir. İkisi arasında ayrım yapmak istiyorum, çünkü "soyutlama" demek, soyutlamanın tanımı "temel özün çıkarılması süreci" gerçek şeyler veya olaylar ".
James

6

Soyutlamanın bir amaç için olduğunu hatırlamak önemlidir. Programınız boyunca tek biçimli davranış için soyutlamayı kullanır ve yeni sınıfların eklenmesini beklediğiniz durumlarda ancak yalnızca o anda soyutlamaya ihtiyaç duyulduğunda yeni sınıfların eklenmesini kolaylaştırırsınız.

Soyutlamaya sadece ihtiyacınız olduğu için eklemeyeceksiniz (düşünmek için gerçek bir temel olmadan gelecekte yeni sınıflar eklemeniz gerekecek). Burada uygun bir metafor tesisat olabilir. Umarım suyun yukarı / aşağı, doğu / batı, kuzey / güney akışını sağlayan 6 yönlü bir borunun, sahip olabileceğiniz en esnek boru türü olacağını kabul edersiniz. Teorik olarak bir borunun gerekli olduğu her yerde 6 yönlü bir boru kullanabilir ve gereksiz yönleri engelleyebilirsiniz, değil mi?

Lavabonuzun altındaki bir sızıntı ile ilgili bir sorunu düzeltmeye çalıştıysanız ve borunun tüm bölümlerinin 6 yönlü boru parçaları olduğunu tespit ettiyseniz, saçınızı bu şekilde tasarlayan adama hayal kırıklığıyla çıkarmak istersiniz. Sadece sorunun nerede olduğunu bilmekle kalmaz, aynı zamanda uygun bir şekilde yapılan sıfırdan başlamak neredeyse daha kolay olur.

Tabii ki kodlama sıhhi tesisat değil , ama mecaz hala duruyor. Soyutlama, bu 6 yönlü boru parçalarını kullanmak gibidir. Dürüst bir şekilde , yakın gelecekte bir gün 6 yönden boru bağlamanız gerektiğine inanıyorsanız bunları kullanın . Aksi takdirde, soyutlama basitçe karmaşıktır, hiçbir şeyin gerekli olmadığı bir desen kullanmaktan veya her şeyi yapmaya çalışan bir tanrı sınıfı kullanmaktan çok farklı değildir. Kullanılmıyorsa ve muhtemelen hiç kullanılmayacaksa, sonuçta hiçbir şey için ek bir sınıf eklersiniz.

Kuşkusuz, program yazma sanatı kavramsal olarak çok soyuttur. Sadece bir soyutlama uğruna soyutlamaların olmadığını, ancak gerçek anlamda pratik olduklarını belirtmek gerekir . Soyutlama kullanma gereğini hissediyorsanız, öyle olun, ancak daha sonra sıhhi tesisatınızı kontrol etmemi istemeyin. ;)


Biraz classmerkezli görünüyorsunuz … Çok fazla sınıf olsa bile, soyutlama bunlarda kullanılmak / faydalanmakla sınırlı değildir.
Deduplicator

1
@Deduplicator Yeterince adil, ama bu benim fikrimi değiştirmiyor. Soyutlama kullanılırsa, derhal faydalı olmalı veya yakın gelecekte planlı bir değişiklik olmalıdır. Sınıflardan veya fonksiyonel programlardan bahsettiğimiz önemli değil.
Neil

3

Nesneye Dayalı Analiz ve Tasarım'ı öğrendiğimde, yıllar önce, müşterinin ihtiyaç duyduğu sistemin basit bir İngilizce açıklaması ile başlayacağız.

Buna bakıldığında, herhangi bir isim (veya isim cümlesi) olası bir sınıf olarak kabul edilir. Herhangi bir fiil (veya fiil cümlesi) sınıflar üzerinde potansiyel yöntemler olacaktır. Yani "torbalama robotu" bir sınıf olabilir BaggingRobot. "Torbayı aç" yöntemi olabilir OpenBag.

Birkaç tekrardan sonra, bu bir sınıf diyagramına dönüşecektir.

Bu noktada, soyut sınıflar yoktur. Müşteri, torbalama robotunun soyut bir konseptini istemiyor. Eşyaları torbalara koyan bir robot istiyorlar. Tüm sınıflar somuttur ve bir dizi yöntemi vardır.

Soyut sınıflar ancak aşağıdakiler belli olduğunda ortaya çıkar:

  • Bir hiyerarşi oluşturabilecek benzer sınıflar vardır.
  • Aslında ortak bir şey paylaşırlar, böylece bir temel sınıf yararlı bir amaç yapar.

Bana göre, "erken soyutlama", herhangi birinden miras kalması BaggingRobot gerektiğiniBaseRobot ve daha da kötüsü, BaseRobottüm robotlar için ortak olanı bile bilmeden önce bir dizi yöntem geliştirmeye çalıştığını varsayar .


Soyutlama soyut sınıflarla eş anlamlı değildir. Bir arayüz bir soyutlamadır. Sadece soyut sınıflardan değil genel olarak soyutlamalardan bahsediyorum. Belki de bunu bir arayüz kullanarak daha net yapabilirdim. Sisteminizi müşterinizle aynı soyutlama katmanında geliştirirseniz, dil doğal olarak soyut olduğu için genişletilmesi gereken bazı soyut sınıflarla sonuçlanmanız muhtemel olacaktır. Bundan daha düşük çalışmak, müşterilere sistemin nasıl çalışacağına dair fikirlerinin sizinkilerle aynı olduğunu varsaydığınız "erken somutlaşma" dediğim şeydir.
James

Öğe nesnelerini Torba nesnelerine koyan bir BaggingRobot nesnesi, şeyleri torbalara koyan gerçek bir torbalama robotunun bir soyutlamasıdır.
user253751

1

Henüz var olmayan bir sorunu çözmek istediğiniz gibi görünüyor ve istemcinin istediği şeyde yanlış olduğuna inanmıyorsanız, gerçekleşeceğini varsaymak için iyi bir nedeniniz yok. Bu durumda, soyut ya da başka bir tahmin çözümü uygulamak hakkında daha fazla iletişim öneriyorum. Sınıf tanımına sadece "soyut" atmak zararsız gibi görünse ve daha sonra genişletebileceğinizi bilerek kendinizi güvende hissetmenize rağmen, asla ihtiyaç duymayacağınızı veya tasarımınızı aşırı karmaşıklaştıracak şekilde kendinizi genişlettiğinizi görebilirsiniz. yanlış şeyleri soyutlayarak.

Örneğin, robotun kendisi , torbalanan nesneler veya hattı değiştirecek torbalama yöntemi olduğunu düşünüyor musunuz?

Erken soyutlama, gerçekten de soyutlamayı gerçekleştirmek için iyi bir nedeniniz olmadığı anlamına gelir ve soyutlamalar birçok dilde ücretsiz olmaktan uzak olduğu için, gerekçe göstermeden yüke maruz kalabilirsiniz.

Düzenle OP'deki bazı noktaları cevaplamak için, bunu (1) ve (2) noktalarını daha spesifik olarak ele alırken uzun bir yorum zinciri gerektirmeyen bir şekilde açıklığa kavuşturmak ve yanıtlamak için güncelliyoruz.

(1) Bana göre bu programcı yeterince pragmatik değil gibi, son programda olmayan şeylerin var olacağı varsayımlarında bulundular, bu yüzden düşük düzeyde bir soyutlama ile çalışıyorlar, sorun değil erken soyutlama, bu erken betonlaşmadır.

(Vurgu madeni). Nihai programda bir şeylerin var olacağını varsaymak, tam olarak senin örneğinde gördüğüm şey değil. Müşteri bir eşya paketleme robotu istedi. Bu, dilinde biraz belirsizse, çok özel bir taleptir. Müşteri, eşyaları taşıyan bir robot istiyor, böylece bir çift nesne üretiyorsunuz

public class Item {
/* Relevant item attributes as specified by customer */
}
public class BaggingRobot {
  private Collection<Item> items;

  public void bag(Item item);
}

Modeliniz basit ve hassastır, çözüme herhangi bir karmaşıklık eklemeden ve müşterinin istediklerinden daha fazlasını istediği varsayımı yapmadan müşteri tarafından belirlenen gereksinimleri takip eder. Bununla birlikte sunulduğunda, robotun değiştirilebilir torbalama mekaniğine sahip olma ihtiyacını açıklarlarsa, ancak o zaman artık eklenmiş belirli bir değere işaret edebileceğiniz için bir arayüz veya başka bir soyutlama yöntemi oluşturmayı haklı çıkarmak için yeterli bilgiye sahipsiniz . sistem soyutlama yoluyla.

Aksine, saf pragmatizmden soyutlama ile başlarsanız, ya ayrı bir arayüz oluşturmak ve onu bir betonda uygulamak ya da soyut bir sınıf ya da istediğiniz herhangi bir soyutlama yaratmak için zaman harcarsınız. Daha sonra müşterinin bundan memnun olduğu ve daha fazla uzatma gerekmediği ortaya çıkarsa, zaman ve kaynakları boşuna harcadınız ve / veya kazanç olmadan sisteme ek yük ve karmaşıklık getirdiniz.

(2) ile ilgili olarak , önemli şeyleri atlamanın yüzünde erken soyutlamanın ayırt edici özelliği olmadığını kabul ediyorum . Soyutlama ya da değil, önemli bir şeyi atlayabilirsiniz ve bir soyutlama zincirinin çizgisinde çok fazla bulunmadıkça, bunu her iki şekilde sıralamak daha zor ya da daha kolay olmayacaktır.

Bunun yerine , herhangi bir soyutlamanın etki alanı modelinizi gizleme riski taşıdığı anlamına gelir. Etki alanı modelinin ve etki alanı anlayışının daha da büyümesini önemli ölçüde etkileyebilecek ilişkiler oluşturduğunuz için, yanlış soyutlama bir sistemin akıl yürütmesini zorlaştırabilir. Sen değil önemli bilgiler atlayarak riskiyle şey soyutlanmış olan , ama yaklaşık bir bütün olarak sistemin yanlış tavşan deliğine modelinizi alarak.


"Henüz var olmayan bir sorunu çözmek istediğiniz gibi görünüyor ve istemcinin istediği şeyde yanlış olduğuna inanmıyorsanız, gerçekleşeceğini varsaymak için iyi bir nedeniniz yok." - Bu söylediğim gibi değil, aslında sadece müşterinin kullandığı kelimelere dayanarak inşa ettiğimi netleştirdim. Bu beni yapmak istememe eylemi soyutlamaları kullanarak beni yönlendirdi.
James

"Tahmin çözümünün uygulanması konusunda daha fazla iletişim öneriyorum" - Yani önerdiğim gibi mi? OP'de söylediklerimi alıntılamak için "bunun çözümü, yanlış tahmin ettiğinizi öğrendiğinizde kendi betonunuzu ve atık kaynaklarınızı bulmak değil, müşteriden daha fazla bilgi almaktır."
James

"Sınıf tanımına sadece 'soyut' tokat atmak ve daha sonra genişletmek bilmek güvenli hissediyorum zararsız gibi görünebilir" - "soyutlama" dediğimde "soyutlama" demek istiyorum "soyut anahtar kelime" demek istemiyorum. Arayüzler soyutlamalar olabilir, soyutlamalar bulanık mantıktır, bu yazının tamamı budur. Müşteri soyutlamalar açısından iletişim kuruyor, bu yüzden alan hakkında daha fazla bilgi edinene kadar soyut terimlerle programlamalıyız.
James

1
"asla ihtiyacınız olmadığını görebilirsiniz" - Bu hiç mantıklı değil. Bir müşteri "Eşyaları taşıyan bir robot istiyorum" diyor, bu kriterleri karşılayan bir soyutlama yaratıyorsunuz. İstemciden aldığınız daha fazla bilgi, torbalamanın nasıl yapılmasını istedikleri hakkında ayrıntılı bilgi olacaktır. Bu, soyutlamanızı geçersiz kılmaz, müşteri, satın aldıkları şeyin ardındaki temel bir fikir hakkındaki fikrini aniden değiştirmez. Robot hala eşyalarını toplayacak. Oluşturduğunuz soyutlama hala geçerli olacaktır.
James

“ya da yanlış şeyleri soyutlayarak tasarımın çizgisini aşırı karmaşıklaştıracak şekilde kendinizi bulabilirsin.” ... Dürüstçe söylediklerimi ya da sadece başlığı okudun mu? Ciddi anlamda? Okuma noktası (1) ve (2)
James
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.