Ayrıntıları soyutlamalar yoluyla gizlemenin değeri nedir? Şeffaflıkta değer yok mu?


30

Arka fon

Ben büyük bir soyutlama hayranı değilim. Arayüzlerin uyarlanabilirlik, taşınabilirlik ve yeniden kullanılabilirlik vb. Faydalarından yararlanabileceğini kabul edeceğim. Orada gerçek fayda var ve bunu sormak istemiyorum, o yüzden görmezden gelelim.

Uygulama mantığını ve ayrıntılarını bu soyutlamanın kullanıcılarından gizlemek olan soyutlamanın diğer büyük "yararı" da vardır. Argüman, detayları bilmek zorunda olmadığınız ve bu noktada kendi mantıklarına odaklanmanız gerektiğidir. Teoride mantıklı.

Ancak, ne zaman büyük kurumsal uygulamaları sürdürürsem, her zaman daha fazla ayrıntı bilmem gerekir. Sadece bir şeyin tam olarak ne yaptığını bulmak için soyutlamada daha derin ve daha derin kazma yapan büyük bir güçlük haline gelir; yani kullanılan saklı yordamın bulunmasından önce yaklaşık 12 kez “açık beyan” yapılması gerekiyor.

Bu 'ayrıntıları gizle' zihniyeti sadece yoluna girmiş gibi görünüyor. Her zaman daha şeffaf arayüzler ve daha az soyutlama yapmak isterim. Yüksek seviye kaynak kodunu okuyabilir ve ne yaptığını bilirim, ancak ne yaptığını, ne zaman yaptığını, gerçekten bilmem gereken şeyi asla bilemeyeceğim.

Burada neler oluyor? Çalıştığım her sistem kötü bir şekilde tasarlandı mı (en azından bu açıdan)?

Benim felsefem

Yazılım geliştirdiğimde, ArchLinux felsefesi ile yakından ilgili olduğunu düşündüğüm bir felsefeyi takip etmeye çalıştığımı hissediyorum :

Arch Linux, GNU / Linux sisteminin doğasında var olan karmaşıklığı korurken, iyi organize ve şeffaf olmalarını sağlar. Arch Linux geliştiricileri ve kullanıcıları bir sistemin karmaşıklıklarını gizlemeye çalışmanın aslında daha da karmaşık bir sisteme yol açtığından ve bundan kaçınılması gerektiğine inanmaktadır.

Bu nedenle, yazılımımın karmaşıklığını soyutlama katmanlarının arkasına asla saklamaya çalışmıyorum. Soyutlamayı kötüye kullanmaya çalışıyorum, köle olmayacağım.

Kalbinde soru

  1. Ayrıntıları gizlemenin gerçek değeri var mı?
  2. Şeffaflığı feda etmiyor muyuz?
  3. Bu şeffaflık değerli değil mi?

7
Soyutlama, kötü tasarım biçiminde kötüye kullanılabilir. Ancak bu, soyutlamanın ilke olarak değerli olmadığı anlamına gelmez.
Bernard

4
Bence orada iyi bir soru var, ancak soyutlamaya karşı bir rant gibi çok şey okuyor. Bunu vurguluyup, asıl sorunuzu daha fazla ortaya çıkarabilir misiniz?
PersonalNexus,

4
"Ayrıntıları gizleme" nin doğru tanımını kullandığınızdan emin misiniz? Bu bağlamda, bir şeyin içsel işlerini öğrenmenizi engellemekten ibaret değil, eşleşmeyi azaltmakla ilgilidir .
Andres F.

24
Masanızda bir voltmetre ve osiloskopla programlama yapmak istemiyorsanız, soyutlamalar üzerine soyutlamalar yerine soyutlamalar dışında hiçbir şeye karşı programlama yapmıyorsunuz. Gerçekte bitleri değil gerçekte gerilimleri manipüle ettiğinizin detaylarını gizlemenizin değeri var mı? Bunu yapmak şeffaflığı feda ediyor mu? Bu şeffaflık değerli midir?
Eric Lippert

8
Bence sorunlarınız soyutlama değil, hiçbir şeyi soyutlamayan boş bir dolaylı katmandır. Evet, bunlar genellikle büyük işletme sistemlerinde bulunur ve hayır, iyi değillerdir.
Michael Borgwardt

Yanıtlar:


47

Ayrıntıları gizlemenin nedeni, ayrıntıları gizli tutmak değildir; bağımlı kodları kırmadan uygulamayı değiştirmeyi mümkün kılmaktır.

Bir nesne listeniz olduğunu ve her nesnenin bir Nameözelliği ve başka verileri olduğunu hayal edin . Ve çoğu zaman, listede Namebelirli bir dizeyle eşleşen bir öğe bulmanız gerekir .

Açık bir şekilde, her bir öğenin üzerinde birer birer döngü oluşturmak Nameve dizeyle eşleşip eşleşmediğini kontrol etmektir . Ancak bunun çok zaman aldığını tespit ederseniz, (listede birkaç bin öğeniz varsa), onu bir dize nesnesi sözlük aramasıyla değiştirmek isteyebilirsiniz.

Şimdi tüm aramalarınız listeye geri dönülerek ve bu döngüler üzerinden gerçekleştirildiyse, bunu düzeltmek için yapılacak çok iş var. Bir kütüphanedeyseniz ve üçüncü taraf kullanıcıları kullanıyorsa daha da zor; Eğer dışarı çıkmak ve düzeltemez onların kod!

Ancak FindByName, ad arama işlemini enkapsüle etme yönteminiz varsa, uygulama biçimini değiştirir ve onu çağıran tüm kodlar çalışmaya devam eder ve ücretsiz olarak daha hızlı olur. Soyutlama ve kapsüllemenin gerçek değeri budur.


Buna katılıyorum, ancak bu sorunun amacı değildi. Belirli bir işlevselliği kapsama yönteminin faydalı olduğuna tamamen katılıyorum, ancak bunun her zaman bir sebep olmadığını hissediyorum. Yanlış mıyım?
user606723

3
@ User606723: Olması gerektiği. Bu her zaman olduğu anlamına gelmez . Bazı insanlar bu noktayı anlamıyorlar ve sadece daha fazla katmana daha fazla katman kazıyorlar ve işleri karışıklığa çeviriyorlar. Bu nedenle deneyimli programcıların yeni geliştiricilere, anlayana kadar asla yeni bir teknoloji veya teknik kullanmamalarını tavsiye etmeleri gerekir.
Mason Wheeler

3
@ user606723: Şeffaflık sıkı bağlantıyı teşvik eder, bu yüzden belki de her zaman kötü değil, ancak genellikle.
Malfist

3
Mason'un, yük kültü programlaması biçiminde katmanlara yığılan insanlar için tanımladığı sorun, neden çok fazla kalıtımdan şüphelendiğimin ve kalıtım konusunda kompozisyonun neden tercih edilmesinin gerektiğidir. Java programcıları için özellikle bir sorun gibi görünüyor.
12'de atıyor

2
Hayır, sıkı bağlantı her zaman kötü değildir . Sık sık kötüdür, ancak bundan kaçınmak için büyük uzunluklara gitmek, yumuşak kodlama
Mason Wheeler

16

Kod tamamlama bölümündeki soyutlamayı okudum, bu kaynakların çoğu burada.

Soyutlamanın amacı, "bu nasıl uygulanır?" Diye sorma ihtiyacını ortadan kaldırmaktır. Aradığınızda user.get_id(), idgeri döneceğiniz şeyin bir olduğunu bilirsiniz . "Kullanıcı kimliğini nasıl alıyor?" o zaman muhtemelen ya bir şeye ihtiyacınız yoktur idya get_id()da beklenmeyen ve kötü tasarlanmış bir şey verir.

Tasarlamanıza izin vermek için soyutlamayı kullanıyorsunuz:

a house with doors and windows

tasarım değil

a box with four walls,
    with 3 holes,
        two of which fit panes of glass surrounded by wood frames,
        one that fits a large plank of wood with hinges and a metal knob,
etc.

Bu arayüzlerden bahsetmiyorum. Bu arayüzler iyi. Pek çok farklı soyutlamanın arkasında bölünmüş olan devasa karmaşık sistemlerden bahsediyorum.
user606723

9
@ user606723 O zaman sorunuz soyutlamalardan ziyade aşırı karmaşık tasarım hakkında
Andres F.

3
Kod tamamlandı için +1. Hem soyutlamanın neden tasarlanması gerektiğine hem de yanlış seviyede soyutlamanın neden tasarımı engellediğine dikkat çekiyor. Örneğinizi daha da ileriye taşımak için, eğer imar ofisinde çalışıyorsam, ayrıntılara girmeden evlerinizi düşünmek istiyorum. Ama benim yaptığım gibi evler hakkında düşünürseniz, o zaman bir tane inşa edemezsiniz.
Spencer Rathbun

bu soru kapatılmalı veya unvan değişti
Jake Berger

8

Ayrıntıları gizlemenin gerçek değeri var mı?

Evet. Soyutlamalar sunarak daha yüksek düzeyde düşünebilir ve programlayabiliriz.

Matematik veya matris cebiri olmadan fiziksel sistemlerin modellenmesini hayal edin. Tamamen pratik değil. Benzer şekilde, yalnızca skaler düzeyde programlayabiliyorsak, ilginç sorunları çözemeyiz. Nispeten basit web uygulamaları bile tag lib'ler gibi soyutlamalardan büyük ölçüde yararlanabilir. "Adres giriş alanları" anlamına gelen bir etiketi tekrar tekrar dört metin alanı ve bir seçim kutusu oluşturmaktan daha kolaydır. Ve yurtdışını genişletmeye karar verirseniz, uluslararası adresleri işlemek için her formu sabitlemek yerine, yalnızca etiket tanımını değiştirebilirsiniz. Soyutlamanın etkin kullanımı, bazı programcıları diğerlerinden on kat daha etkili yapan şeydir.

İnsanların sınırlı bir çalışma hafızası vardır. Soyutlama, büyük sistemler hakkında mantıklı olmamızı sağlar.

Aren't we sacrificing transparency?

Hayır. Soyutlamalar kullanılmazsa, bir yazılım bileşeninin amacı tekrarlanan ayrıntılara gömülür. Geliştiriciler, günlerini şu kodla dolaşarak geçirirler:

for (i = 0; i < pilgrim.wives.size(); ++i) {
  wife = pilgrim.wives[i];
  for (j = 0; j < wife.sacks.size(); ++j) {
     sack = wife.sacks[i];
     for (k = 0; j < sack.cats.size(); ++j) {
        cat = sack.cats[k];
        for (m = 0; m < cat.kits.size(); ++m) {
           ++count;
        }
     }
  }
}

ve "ah evet, kitlerin üzerinde başka bir dört seviyeli döngü" düşünerek, yerine

pilgrim.kits.each { ++count; }

Bu şeffaflık değerli değil mi?

Sizin de belirttiğiniz gibi, dolaylı olarak bir bedel var. "Sadece durumda" katmanları oluşturmanın anlamı yoktur. Çoğaltmayı azaltmak ve kodu netleştirmek için soyutlamayı kullanın.


7

İnsanlar soyutlamaların uygulama detaylarını gizlediğini söylerken, aslında bulmayı zorlaştırmak anlamında "saklanmak" anlamına gelmez. Demek istedikleri, arayüzü basit, özlü ve yönetilebilir tutmak için uygulama detaylarını ortak arayüzden ayırmaktır. Tıpkı bir otomobil gibi hayati parçalarının çoğunu "gizler" ve sadece onları çalıştırmak için oldukça basit bir kontrol seti sunar, bir yazılım modülü işlevselliklerinin çoğunu bağırsaklarında derinlemesine "gizler" ve sadece sınırlı sayıda erişim yöntemini ortaya çıkarır sür onu. Tüm motorun iç kısımlarını manuel olarak çalıştırmak zorunda olduğunuz (ve çok çılgınca bir sürü var) bir araba hayal edin, trafiğe göz kulak olmak ve yolu bulmak için gerçekten zor zamanlar geçirirsiniz.

Ancak arayüzü basit tutmak sadece estetik bir şey değildir; Başarılı bir proje ve Ölüm Marşı arasında fark yaratabilir. Bir dakika şeytanın avukatını oynayalım; soyutlama yapmadan bir yazılım projesi hayal edin. Çevresinde bir değer tutmanız gerekirse, genel bir değişken kullanırsınız. İşlevselliği bir kereden fazla kullanmanız gerekirse, kopyala-yapıştır yöntemini kullanırsınız. Belirli bir kod bölümünün iki farklı sürümüne ihtiyacınız varsa, kopyalayıp yapıştırın, bir ififadeye sarın ve her iki dalı da değiştirin. Teknik olarak konuşursak, işe yarıyor ama yoldan birkaç ay sonra çok kötü bir problemle savaşıyor olacaksınız:

  • Bir hatayı bulduğunuzda ve düzelttiğinizde, benzer kodun diğer kopya yapıştırılmış örneklerinde de bulunma olasılığı yüksektir, bu nedenle hatayı bulma ve düzeltmenin yanı sıra, diğer oluşumları aramaya ve bunları düzeltmeye de devam etmeniz gerekir.
  • Bir hata bulmak veya bir değişikliği uygulamak için, bir bakım programcısı ilgili kodu anlayabilmelidir. Bunu yapmadaki zorluk ilgili kod bölümünün büyüklüğü ile artar, ancak kapsamı daha da artar. Zihinsel olarak bazı kodların üzerinden geçerken yarım düzine değişkeni kafanızda tutmak mümkündür; ancak birkaç yüzünüz varsa, üretkenliğiniz ciddi şekilde etkilenir (düşünce sürecini fiziksel RAM'im biten ve takas dosyasına dalmak zorunda olan bir programla karşılaştırmayı severim: bir seferde akıcı kodları okumak yerine , programcı şeyleri aramak için ileri geri atlamak zorundadır).
  • Bir kod parçasının kapsamı ayrıca bir hatayı bulmak için kazmak zorunda olduğu kod tabanının boyutunu da etkiler. İki parametreli ve küresel olmayan on satırlık bir işleve sahipseniz ve girişin değerinin ve çarptığı satırın değerini biliyorsanız, hatayı bulmak genellikle önemsizdir ve çoğu zaman koda bakmaktan başka bir şey gerektirmez. Birkaç yüz çizgi, yirmi parametre, on beş küre ve benzer nitelikteki birkaç başka işlevi çağırıyorsa, ciddi bir acı çekeceksiniz demektir.
  • Doğru bir soyutlama olmadan, herhangi bir değişiklik potansiyel olarak kod tabanının büyük bölümlerini etkileyebilir, çünkü pratikte her şey değiştirilecek koda bağlı olabilir. Bu tür kod tabanları ile ilgili tipik bir belirti, küçük, görünüşte masum bir değişiklik yapmanız ve tamamen ilgisiz bir özelliği aniden kırmanızdır. Soyutlama ile, bir değişimin yapabileceği hasar miktarını sınırlayabilir ve etkiyi daha öngörülebilir hale getirebilirsiniz. Özel bir alanın adını değiştirirseniz, kontrol etmek için yalnızca bir kaynak dosyanız vardır; eğer bir global değişkenin adını değiştirirseniz, kod kodunun tamamını kullanmanız gerekir.

Kötü soyutlanmış bir kod tabanında, etki tipik olarak kod tabanının boyutuyla üssel olarak artar, yani, sabit miktarda kod eklenmesi, bakım eforunu sabit bir faktörle artırır. İşleri daha da kötüleştirmek için, bir projeye daha fazla programcı eklemek, doğrusal olarak verimliliği artırmaz, ancak en iyi şekilde logaritmik olarak çalışır (çünkü ekibiniz ne kadar büyükse iletişim için daha fazla ek yük gerekir).


2

Gerektiğinde nasıl çalıştığını anlaman gerektiğini düşünüyorum. Bir kere yapacağını düşündüğün şeyi yaptığını belirledikten sonra, gönül rahatlığına sahip olacaksın. Asla amacın onu sonsuza dek saklamak olduğunu düşünmedim.

Çalıştığından emin olduğunuz bir saatte bir alarm ayarladığınızda, corret zamanında çalışacağını bilerek biraz uyuyabilirsiniz. Sadece bir saat erken kalkmak, böylece kene saniyelerinizi izleyebilmeniz israf olur.


1
Tabii, ancak sık sık alarm saatimin çalışma şeklini değiştirmem istenmiyor veya başkalarının alarm saatimin çalışıp çalışmadığı değişiklikleri tam olarak bilmeden değiştirmelerini istemiyorum.
user606723

1
Kullandığınız her çerçeve için kod değişikliklerini görüyor musunuz?
JeffO

1
hayır, ancak şimdiye kadar kullandığım her çerçeve için kod değişiklikleri yapmıyorum.
user606723

3
JeffO'nun amacını kanıtladınız: Alarm saatlerini sürdürme işinde değilsiniz. Bir tane satın alır ve tam bir yırtma işlemi yapmadan ve nasıl çalıştığını analiz etmeden kullanmaya başlarsanız, iç kısımların sizin için soyut olacağını kabul ettiniz. Hiçbir şey nasıl çalıştığını bulmak için onu ayıramayacağınızı söyleyemez , ama ne kadar sıklıkla gerekli buluyorsunuz?
Blrfl

2

Sorularınıza özellikle cevap vermek için:

Ayrıntıları gizlemenin gerçek değeri var mı?

Evet. Sorunuzun ilk satırında kabul ettiğiniz gibi.

Şeffaflığı feda etmiyor muyuz?

Pek sayılmaz. İyi yazılmış bir soyutlama, gerektiğinde ayrıntıların anlaşılmasını kolaylaştıracaktır.

Bu şeffaflık değerli değil mi?

Evet. Soyutlamalar, ihtiyaç duyulduğunda / istendiğinde ayrıntıların anlaşılmasını sağlamak için tasarlanmalı ve uygulanmalıdır.


Sonunda sevdiğim bir cevap.
user606723

1

Gizli şeyler işe yaradığında ayrıntıları gizlemenin harika olduğunu söyleyebilirim.

Örneğin, kullanıcı tarafından bir düğme tıklaması veya başka bir şeyle başlatılan iki özellik olan davranışları (örneğin GetListItems, SendListItem) tanımlayan bir arayüz geliştirdiğimizi söylüyoruz. ŞİMDİ, her kullanıcı kendi "ListItemStore" .. sayılabilir. biri facebook'ta, myspace'de olanlar .. (mesela) .. ve kullanıcı tercihi olarak kaydedilmiş olduğunu söylüyorlar / uygulamadaki herhangi bir yere kullanıcı tercihleri ​​kullanılarak ayarlanmışlar .. ve Uygulama geliştiricilerin ders listesine ilave ListItemStore'lar ekleyebileceğini söylüyorlar. zaman (mybook, facespace, vb.)

şimdi facebook'a bağlanmak ve bunları öğelerini almakla ilgili birçok ayrıntı var .. ve myspace'e bağlanırken de aynı miktarda ayrıntı var ..

Şimdi, ilk "mağaza erişimi" kodu yazıldıktan sonra, değiştirilmesi gerekmeyebilir (facebook durumlarında, muhtemelen değişikliklere ayak uydurabilmemiz için tam zamanlı bir geliştiriciye ihtiyacımız vardır, zing ..),

kodunu kullandığınızda şöyle bir şey:

    new ItemManager(user) //passes in user, allowing class to get all user properties
    ItemManager.GetListItems()

ve şimdi, Kullanıcının verilerini nereye depoladıkları yerden alıyorsunuz ve endişelendiğimden beri, ürünlerin listesini almak ve onunla bir şeyler yapmak ve ne olursa olsun işe yarayacak sadece 2 satır sürdüğü için çok daha fazla mağaza eklendi ben soru cevaplama / gönderme sorulara geri alabilirsiniz ... lol ..

Bu yüzden, bunun gerçekleşmesi için gereken tüm tesisatlar "gizli" ve doğru parçaların listesini aldığım sürece bunun nasıl yapıldığını gerçekten umursayan .. birim testleriniz varsa, o zaman daha kolay dinlenebilirsiniz çünkü sonuçların ... çoktan ölçüldü ..


Evet, ama korunması gereken kısım asla bu iki satır değildir. Bunları mahvetmek imkansız. Değiştirmeniz gereken her zaman 2., 3., 4. seviyedir. Kararlı olacağınıza güvenebileceğiniz bir API'niz olduğunda bunun harika olacağını kabul ediyorum, peki ya işinizin karmaşıklığı nedeniyle kararlı olamazsa?
user606723

1
@ user606723 Eğer API kararlı değilseniz, o zaman muhtemelen olgunlaşmamış veya yanlış soyutlama olasılığı daha yüksektir
sdg

@ user606723 - Bu doğru ve kuralların isimlendirilmesi durumunda, kendileri gerçek programlama mantığını / detayını gizleyen bir çeşit şeffaflık tanımlamalıdır .. ve gerçek kaynağı değiştirmek zorunda kalırsanız, daha fazla detay ve fikirler bilgilendirici adlandırma yoluyla ifade edilmelidir. Bu yüzden özünde, şeffaflık baştan aşağı doğru adlandırma ile gerçekleştirilebilir, ancak gerçekten sık sık aşağı inmemize gerek yoktur.
hanzolo

sdg, veya sistemin gereksinimleri her zaman değiştiğinden. Yasalar değiştiği için, diğerlerinin API'leri değiştiğinden, bizim kontrolümüz dışında.
user606723

1
@ user606723 - Aslında bir finansal SaaS sistemi üzerinde çalışıyorum ve her sürüm döngüsünde yeterli soyutlamaya sahip olmamanın tuzaklarını görüyorum. bir kısmı, zayıf tasarımın bir sonucudur, ancak genellikle başlangıçta amaçlanmadığı yerlerde zorlama kodunun sonucudur. Zincir aşağı inmek bu yorumlar, isimler ve enkapsülasyon olmadan acı verici olabilir . tek yapmam gereken Remeasurements.GetRemeasureType (grant) ve sonra reMeasure.PerformCalc () olsaydı, bu doğru bir hesaplama yapmak veya yeni bir tane eklemek için aşırı yük eklemek ve farklı mantıksal dallar okumaktan çok daha güzel olurdu
hanzolo

1

“Saklanmak” olarak adlandırdığınız şey, çoğu kaygılarınızın ayrılması olarak görüyor (ör. Uygulama ve Arayüz).

Benim düşünceme göre, soyutlamanın en büyük yararı, gereksiz ayrıntıların dağınıklığını, geliştiricinin sınırlı beyin fırtınasından azaltmaktır.

Uygulama kodu gizlendiyse, şeffaflığı engelleyen, ancak gördüğüm gibi soyutlamanın sadece iyi bir organizasyon olduğunu görebiliyordum.


1

Öncelikle, tek bir makine kodu talimatının ötesindeki herhangi bir şey esasen soyutlamadır - while...dodöngü, bir koşul yerine getirilinceye kadar bir dizi talimatı tekrarlamak için gereken karşılaştırmaları ve adres aramalarını temsil etmenin tutarlı bir sembolik yoludur. Benzer şekilde, int türü, X bit sayısı için bir soyutlamadır (sisteminize bağlı olarak). Programlama tamamen soyutlama ile ilgilidir.

Muhtemelen bu ilkel soyutlamaların çok faydalı olduğu konusunda hemfikirsiniz. Öyleyse kendine ait bir şey inşa edebiliyorsun. OOAD ve OOP hepsi hakkında.

Kullanıcıların verileri bir ekrandan çeşitli biçimlerde dışa aktarabilmesi için bir gereksiniminiz olduğunu varsayalım: sınırlandırılmış metin, excel ve pdf. Her biri belirli bir çıktının nasıl oluşturulacağını bilen bir DelimitedTextExporter, bir ExcelExporter ve bir PDFExporter oluşturabileceğiniz bir yöntem dışa aktarma (veri) içeren "Aktarıcı" adlı bir arabirim oluşturabileceğiniz kullanışlı değil mi? Çağıran tüm programların bilmesi gereken, export (data) yöntemini çağırabildiği ve hangi uygulamada kullanılacağını yapmasıdır. Dahası, eğer sınırlandırılmış metin kuralları değişirse, DelimitedTextExporter'ı ExcelExporter'la uğraşmak zorunda kalmadan değiştirebilir ve muhtemelen bozabilirsiniz.

OO programlamasında kullanılan iyi bilinen tasarım desenlerinin hemen hepsi soyutlamaya bağlıdır. Soyutlamanın neden iyi bir şey olduğunu daha iyi hissetmek için Freeman ve Freeman'ın Baş İlk Tasarım Desenlerini okumanızı tavsiye ederim.


1
makine kodu bile bir soyutlamadır, dolayısıyla gerçek, fiziksel, mantığın altında gerçekleşen süreçler, dijital elektronikler bile bir çipin overclock yapmasını sağlayan birisinin
jk

Çok doğru, ancak makine talimat düzeyinde daha somut görünse de.
Matthew Flynn

1

Sanırım bu konudaki duygularını anlıyorum ve benim de benzer bir fikrim olduğunu düşünüyorum.

50 kod satırı sınıfını 3 sınıfa ve 3 arayüze dönüştüren Java geliştiricileri ile çalıştım, çünkü anlaşılması kolay. Ve dayanamadım.

Anlaşılması çok zordu, hata ayıklamak neredeyse imkansızdı ve asla "uygulamayı değiştirmesi" gerekmedi.

Öte yandan, birden çok nesnenin benzer davranışı paylaştığı ve tek bir yerde kullanıldığı bir kod gördüm ve yöntemler ortak arabirim aracılığıyla ortaya çıkarılsaydı, genel sıralama / işleme döngüleri kullanabilirdi.

Dolayısıyla, IMHO, benzer senaryolarda kullanılması muhtemel olan çekirdek nesneler genellikle arayüz yoluyla erişilmesi gereken ortak davranışlardan yararlanır. Fakat bu basit bir şeydir, çünkü basit şeyler soyutlamak doğru, ya da uygulamaları değiştirmeyi mümkün kılıyor, sadece kodları karışıklaştırmanın bir yoludur.

Sonra tekrar, tüm yaşam boyu yönetim sorunları olan patlayıcı miktardaki küçük sınıflara göre daha uzun ve daha zorlu ilişkileri, görmesi zor ilişkileri ve spagetti çağrı grafiklerini tercih ediyorum. Yani bazı insanlar benimle aynı fikirde olmayacak.


1

Gizleme ve soyutlama yol gösterici amacı olmalıdır ayırımı onlar bağımsız olarak değiştirilebilir böylece uygulanmasından kullanıcıyı tüketici uygulama ayrıntıları ile birleştiğinde ise sebebiyle taş dökme hem kendi içlerinde ile işe yaramaz olarak belirlediği bu yeni özellikler tanıtmak zorlaşmaktadır veya gelecekte daha iyi algoritmalar.

Bir modül yazarken, uygulamanın gizli kısımları, düşünemeyeceğiniz diğer kodları kırma riski olmadan bunları değiştirebilmenizi sağlar.

Opak arayüzler sağlamanın bir başka avantajı, alt sistemler arasındaki yüzey alanını önemli ölçüde azaltmalarıdır. Etkileşim yollarının miktarını azaltarak daha öngörülebilir, test edilmesi kolay ve daha az hataya sahip olabilirler. Modüller arasındaki etkileşimler de modül sayısı ile dört kat artmaktadır, bu yüzden bu karmaşıklığın büyümesini kontrol etmeye çalışırken bir değer vardır.


Bununla birlikte, elbette çok fazla gizlemek ve arayüzleri çok derinleştirmek mümkündür. Akıllı bir insan olarak programcının işi, sistemi karmaşıklaştırmayı ve bakım kolaylığı en üst düzeye çıkarırken azami derecede yararlı olacak şekilde tasarlamaktır.


0

Pek çok durumda, işlerin nasıl uygulandığını bilmeniz gerekmez . people.Where(p => p.Surname == "Smith")Günde bu kadar çok kez böyle bir kod yazacağınızı garanti ederim, ancak "bu Where()yöntem aslında nasıl çalışır?" Diye düşünmezsiniz. Sadece umursamıyorsunuz - bu yöntemin orada olduğunu ve size istediğiniz sonuçları aldığını biliyorsunuz. Nasıl çalıştığını neden umursuyorsun?

Bu, herhangi bir şirket içi yazılım için de aynıdır; Sırf Oracle, Microsoft vb. tarafından yazılmadığı için, nasıl uygulandığını araştırmak zorunda kalacağınız anlamına gelmez. Size, GetAllPeopleWithSurname(string name)bu soyadı olan kişilerin bir listesini döndürmek için çağrılan bir yöntemin makul şekilde bekleyebilirsiniz . Bir liste üzerinde yinelenebilir, bir sözlük kullanabilir, tamamen çılgınca bir şeyler yapabilir, ancak umursamamanız gerekir .

Elbette bu kuralın bir istisnası vardır (bir kural olmadan olmazdı!) Ve yöntemde bir hata varsa. Yani yukarıdaki örnekte, içinde 3 kişiden oluşan bir listeniz varsa ve bunlardan birinin Smith soyadına sahip olduğunu ve listede bulunmadığını biliyorsanız, o zaman bu yöntemin uygulanmasını önemsersiniz, çünkü açıkça kırılmıştır. .

Soyutlama, doğru yapıldığında harikadır, çünkü daha sonraki bir tarihte okumanız gerektiğinde kullanışlı olmayan tüm şeyleri filtrelemenize izin verir. Unutmayın, kod okumak için harcanan koddan daha fazla zaman harcanıyor, bu yüzden bu görevi mümkün olduğunca kolaylaştırmak üzerinde durulmalı. Ayrıca, soyutlamanın kolunuz kadar uzun bir nesne hiyerarşisi anlamına geldiğini düşünebilirsiniz, ancak her biri 10 satırlık bir 10 satırlık bir 100 satır yöntemini yeniden düzenlemek kadar basit olabilir. Yani bir zamanlar bir araya getirilen 10 adımın hepsi şimdi 10 ayrı adımdır, bu sinir bozucu hatanın saklandığı yere direk gitmenizi sağlar.


Eh, diyelim ki uygulamayı sürdüren sizsiniz. Yani, birisi uygulama ile ilgileniyor ve o kişi sensin. Ayrıca uygulamanın kullanıcısı olursunuz ... İş gereksinimleri değişim (tahmin edemediğiniz şekillerde) birçok katmanda değişikliklere neden olur. Sanırım demek istediğim, bir hatanın bu kuralın tek istisnası olmadığıdır.
user606723

Sorun şuPeopleFactory.People.Strategy.MakePeople.(CoutryLaw.NameRegistry.NameMaker.Make()) as People.Female
Kodlayıcı,

@ user606723 Her zaman kod tabanınızdaki her kod satırıyla ilgilenmeniz gerekmez. Bu uygulamada bir hata varsa veya yeniden yazılması gerektiği için işaretlendi (çünkü yavaş, kötü yazılmış veya ne olursa olsun) ve yeniden yazıyorsanız, o zaman umursuyorsunuz. Aksi takdirde, yolun dışında tutulmalıdır. Belki de sizin probleminiz her zaman tüm kodlara sahip olmaya çalışmaktır. Sadece bence üzerinde çalıştığınız kod üzerinde yoğunlaşmalısınız.
Stuart Leyland-Cole

@Coder Açıkçası bu oldukça soyut bir soyutlama şekli! İlk başta OP'nin karşı çıktığı türden bir şey olduğunu düşünmüştüm ama cevaplarının geri kalanını okumaktan, tüm soyutlamaları kötü kötü olarak görüyorlar. Bu yüzden cevabımdaki farklı soyutlama seviyelerini açıklamaya çalıştım.
Stuart Leyland-Cole

0

Soyutlamalar bilginin gizlenmesiyle sonuçlanır. Bu daha düşük bağlantıda bitmelidir. Bu, daha az değişim riskine yol açmalıdır. Bu, mutlu programlayıcılara yol açmalı, koda dokunurken sinirlenmemelidir.

Bu fikirler yazılım mimarisindeki üç temel yasa ile ifade edilir:

Simon Yasası: "Hiyerarşiler karmaşıklığı azaltır." (Hiyerarşiler soyutlamayı başlatır)

Parna Yasası: "Sadece gizli olanlar risk almadan değiştirilebilir."

Constantin Yasası: Sağlam programlar, düşük bağlantı ve yüksek uyum gerektirir


"Hiyerarşiler karmaşıklığı azaltır." - mutlaka doğru değil.
Kodlayıcı

Hiçbir tasarım metodolojisi belirleyici değildir. Bu yasa IT / CS'den gelmiyor, çok daha geniş bir anlamda formüle edilmiş ve matematik, fizikçiler vb. Tarafından da anılıyor. Bu geçerli bir ilke, ancak kimse saçma hiyerarşileri yaratmanızı engelleyemez.
ins0m

0

Ben de kurumsal uygulama işindeyim ve bu soru da dikkatimi çekti, çünkü aynı soruyu kendim yaptım. Şimdiye kadar kariyerim boyunca soyutlama konusuna dair bazı görüşlerim vardı, ancak görüşüm hiçbir şekilde evrensel bir cevap değil. Yeni fikir ve düşünceleri öğrenmeye / dinlemeye devam ediyorum, bu yüzden şu an değişebileceğini düşünüyorum.

Geniş ve karmaşık bir sağlık bakımı uygulamasının bakımını yaparken, sizden çok hoşlandım, oradaki tüm soyutlamalardan nefret ettim. Bütün kodun nereye gittiğini bulmak, boyundaki ağrıydı. Farklı sınıfların etrafında atlamak beni başım döndü. Ben de kendi kendime “soyutlama berbat, soyutlamalar tasarlarken soyutlamayı minimize edeceğim” dedim.

Ardından, sıfırdan bir uygulama (göreceli küçük web servis bileşeni) tasarlamam gerekti. Bütün acıları hatırlayarak, bileşen için oldukça düz bir tasarımım vardı. Sorun şuydu: ihtiyaçlar değiştiğinde birçok farklı yerde değişiklik yapmak zorunda kaldım (şartlar oldukça akışkandı ve bu konuda hiçbir şey yapamadım). Çok kötüydü, temelde ilk tasarımımı ve yeniden tasarımımı soyutladım ve işler daha iyi hale geldi - gereksinimler artık değiştiğinde birçok yerde değişiklik yapmak zorunda değildim.

Başvuruyu yaptım, birkaç hafta beklettikten sonra başvuruyu sürdürmeye başlamam söylendi. Bir süredir her şeyi hatırlamıyordum, bu yüzden kendi kodumu anlamak için biraz uğraştım ve soyutlama yardımcı olmadı.

Daha sonra pek çok farklı projeye girdim ve soyutlama seviyelerinde biraz daha oynama şansı buldum. Aslında bulduğum şey şudur, ve bu sadece benim kişisel görüşüm, soyutlama gelişimde çok yardımcı olur, ancak kodu yazmadığınızda ve bir uygulamayı en derin seviyedeki her şeyi anlamaya çalıştığınızda olumsuz etkiye sahiptir; farklı sınıfların etrafında atlayarak ve bağlantı kurmaya çalışırken daha fazla zaman harcayacaksınız.

Benim düşünceme göre, soyutlama geliştirme aşamasında o kadar değerlidir ki, kodu anlamaya çalışırken bakıcı olarak yaşadığımız sıkıntı buna değer. İş sorunlarını çözmek için yazılım var, iş sorunları zamanla gelişir; bu nedenle, yazılım zaman içinde gelişmelidir. Soyutlama olmadan, yazılımı geliştirmek çok zordur. Kişi soyutlamayı, kod yapısının modelini gördükten sonra kolayca kod tabanında dolaşabilecek şekilde tasarlayabilir, böylece yalnızca ilk öğrenme eğrisi sinir bozucu hale gelir.


0

Diğerlerinin de dediği gibi, bir soyutlamanın arkasındaki "ayrıntıları gizleme", kullanıcıları etkilemeden değiştirilmelerini sağlar. Bu fikir Parnas'ın Modüllere Ayrıştırma Sistemlerinde Kullanılacak Kriterler Üzerine (1972) gelmektedir ve soyut veri tipleri (ADT) ve nesne yönelimli programlama fikri ile ilgilidir.

Aynı zamanda, Codd'un Büyük Paylaşılan Veri Bankaları için Bir İlişkisel Veri Modeli (1970) , veritabanlarının iç depolama temsilini veritabanının kullanıcılarını etkilemeksizin değiştirmek isteyerek motive edildi (bkz. Özete ve giriş). Programcıların düzenli olarak günler sürdüğünü, küçük sayfa değişiklikleriyle başa çıkabilmek için kod sayfalarını değiştirdiğini gördü.

Bununla birlikte, bir soyutlama, onu kullanabilmek için içinde ne olduğunu görmek zorunda kalırsanız çok kullanışlı değildir. İyi dizayn etmek çok zor olabilir. İyi bir soyutlama örneği, eklemedir - en son ne zaman içeride ne olduğunu düşünmek zorunda kaldınız? (ama bazen, örneğin taşma için).

Temel sorun (IMHO), modülleri iyi bir şekilde tasarlamak için (Parnas'ın anlamında) neyin değişip neyin değişmeyeceğini tahmin etmeniz gerekir. Geleceği tahmin etmek zordur - ancak bir şeyle ilgili çok fazla deneyime sahipseniz ve net bir şekilde anlıyorsanız, o zaman oldukça iyi bir tahmin işi yapabilirsiniz. Bu nedenle, iyi çalışan bir modül (soyutlama) tasarlayabilirsiniz.

Ancak, tüm soyutlamaların kaderi gibi görünüyor - en iyisi bile - sonunda soyutlamanın kırılmasını gerektiren öngörülemeyen (ve tartışmalı, öngörülemeyen) değişiklikler olacak. Bunu ele almak için, bazı soyutlamaların bir kaçışları var; burada gerçekten ihtiyaç duyduğunuzda daha derin bir seviyeye erişebilirsiniz.

Bunların hepsi çok olumsuz görünüyor. Ama bence gerçek şu ki, çok iyi çalışan soyutlamalar ile çevreleniyoruz, onları fark etmiyoruz ya da ne sakladıklarını fark etmiyoruz. Sadece zayıf soyutlamaları görüyoruz, bu yüzden onları sarılıktan görüyoruz.


0

Soyutlamalar çoğunlukla tüketicilerin yararınadır (örneğin, uygulama programcıları). Sistem (tasarımcı) programcıları onları güzel ve kullanışlı kılmak için yapacak daha çok çalışmaya sahiptir, bu yüzden iyi tasarım genellikle yeni başlayanlar tarafından yapılmaz.

Belki de soyutlamaları sevmiyorsunuz çünkü her zaman karmaşıklık ekliyorlar? Belki üzerinde çalıştığınız sistemler soyutlama iltihabına sahiptir (soyutlamaların aşırı kullanımı)? Her derde deva değiller.

Faydalı bir soyutlamanın ekstra çalışması ve karmaşıklığı karşılığını vermelidir, ancak kesin olarak bilmek zor. Bir soyutlamayı bir pivot noktası olarak düşünürseniz, yazılım tasarımı her iki tarafa da bükülebilir: soyutlamanın uygulamaları müşteri kodunu kırmadan değiştirilebilir ve / veya yeni müşteriler soyutlamayı kolayca yeni şeyler yapmak için yeniden kullanabilir.

Neredeyse soyutlamaların yatırım getirisini, bu yönlerden birinde veya her ikisinde de zaman zaman "büküldüklerini" göstererek ölçebilirsiniz: nispeten ağrısız uygulama değişiklikleri ve yeni müşteriler.

Örneğin: Java'da Socket sınıfının soyutlamasını kullanarak, Java 1.2'deki uygulama kodumun Java 7 altında hala iyi çalıştığından eminim (bazı performans değişiklikleri olsa da). Java 1.2'den bu yana, bu soyutlamayı da kullanan pek çok yeni müşteri oldu.

Soyutlamalar ile mutsuzluk gelince , Socket sınıfının arkasındaki kodu koruyan geliştiriciler ile konuştuysam , belki de hayatları eğlenceli uygulamalar yazmak için Socket'ı kullanan müşteriler kadar şeftali ve pembe değildir. Bir soyutlamanın uygulanması konusunda çalışmak kesinlikle onu kullanmaktan daha fazla iş. Ama bu onu kötü yapmaz.

Şeffaflık gelince, yukarıdan aşağı bir tasarım stratejisinde, toplam şeffaflık kötü tasarım için yapar. Akıllı programcılar, ellerinde oldukları bilgilerden en iyi şekilde yararlanma eğilimindedir ve sistem daha sonra sıkı sıkıya bağlanır. Bir modülde en küçük detay değişikliği (örneğin, bir veri yapısındaki baytların sırasını değiştirmek) bir başka kodu bozabilir, çünkü akıllı bir programcı bu bilgiyi faydalı bir şey yapmak için kullandı. David Parnas, bu sorunu 1971 yılına kadar olan makalelerde , tasarımlardaki bilgileri gizlemeyi önerdiğini belirtti.

İşletim sisteminin "içini" işletim sistemi üzerinde çalışan soyutlamanın karmaşık bir uygulaması olarak görüyorsanız, ArchLinux'a referansınız bana mantıklı geliyor. Soyutlamanın bağırsaklarında basit tutun.


0

Sorunuza bir soru ile cevaplayacağım; bu sabah işe gittikten sonra (aslında öyle yaptığını farzedeceğim), motorun yakıt-hava karışımlarına girmesi için vanaları nasıl açtığını ve sonra onları ateşlediğini düşündün mü? Hayır . Yolda sürerken aracınızın motorunun nasıl çalıştığını umursamıyorsunuz . Sen o bakım yapar işi.

Diyelim ki bir gün arabanız çalışmıyor. Başlamaz, bir çubuk fırlatır, bir kemeri kırar, mesajlaşmakla meşgul olduğunuzda kendi barızlığınız olmadan açık bir şekilde bu bariyere girer. Şimdi, yeni bir arabaya ihtiyacınız var (en azından geçici olarak). Bu yeni arabanın nasıl çalıştığını tam olarak önemsiyor musunuz? Hayır. Önemsediğiniz şey, önce işe yaradığı, ikincisi ise eski arabanızı yenisini sürmek için kullandığınız bilgi ve becerileri kullanabilmenizdir. İdeal olarak, kullandığınız araçta hiçbir değişiklik olmadığı size anlaşılmalıdır. Gerçekçi olarak, bu yeni arabanın çalışma şekli size mümkün olduğunca az “sürpriz” vermeli.

Bu temel ilkeler, kapsülleme ve soyutlamanın arkasındaki ana ilkedir. Bir nesnenin yaptığı şeyi nasıl yaptığını bilmek, yaptığı şeyi yapmak için onu kullanmanın zorunlu olmamalıdır. Bilgisayar programlamasında bile, programınızı çalıştıran CPU içindeki elektrik yollarının detayları, en az yarım düzine G / Ç talimatı, sürücü, işletim sistemi yazılımı ve çalışma zamanı katmanının arkasında kalıyor. Çok başarılı yazılım mühendislerinin birçoğu, tam bir donanım mimarisi, hatta işletim sistemi kurulumundan endişe duymadan mükemmel bir kod yazar. Ben dahil.

Kapsülleme / bilgi gizleme "nasıl yaparsa umursama, sadece yaparsa umursama" zihniyetine izin verir. Hedefiniz, tüketicinin kolay kullanabileceği şekilde tüketiciye neyin yararlı olduğunu göstermelidir. Şimdi, gerçek dünyaya dönersek, bu bir otomobilin kullanıcıya iç çalışmalarla ilgili herhangi bir bilgi vermemesi gerektiği veya otomobilin kullanıcıya yalnızca ateşleme, direksiyon simidi gibi en temel işlevselliklere izin vermesi gerektiği anlamına gelmez. ve pedallar. Tüm otomobillerde hızölçerler ve yakıt göstergeleri, takometreler, salak ışıklar ve diğer geri bildirimler vardır. Neredeyse tüm arabalarda ayrıca farlar, dönüş sinyalleri, telsiz, koltuk ayarı vb. Gibi çeşitli bağımsız alt sistemler için anahtarlar bulunur. Bazı araçlar sınırlı kaymalı merkez farkının hassasiyeti gibi bazı oldukça ezoterik kullanıcı girişine izin verir. Her durumda, eğer yeterince biliyorsanız, açabilir ve biraz farklı bir şekilde çalışmasını sağlamak için şeyleri değiştirebilirsiniz. Ancak, çoğu durumda, belki, sadece belki, kullanıcı yakıt pompalarını doğrudan ve bağımsız olarak kabinin içinden kontrol edememelidir? Belki, sadece belki, kullanıcı fren pedalına basmadan, fren lambalarını yakamamalıdır?

Soyutlama, "bu aynı değildir, ancak her ikisi de XI olduğu gibi onları herhangi bir X’in kullanabileceği" zihniyetine izin verir. Nesneniz bir soyutlamayı miras alırsa veya uygularsa, tüketicileriniz uygulamanızın soyutlamanın bilinen diğer uygulamalarıyla aynı veya benzer bir sonuç üretmesini beklemelidir. Bir Toyota Camry ve bir Ford Fusion, "araba" dır. Bu nedenle, direksiyon gibi ortak bir beklenen işlevlere sahiptirler. Saat yönünün tersine çevirin, araba sola gider. Saat yönünde çevir, araba sağa gider. Amerika Birleşik Devletleri'ndeki herhangi bir araca binebilir ve aracın bir direksiyon simidi ve en az iki pedala sahip olmasını bekleyebilirsiniz; sağda biri "araba gider" pedalı ve merkezde "araba durur" pedalı .

Soyutlamanın bir sonucu olarak "en az şaşkınlık teorisi" denir. Test sürüşü için yeni bir arabanın direksiyonuna geçtiyseniz, direksiyon simidini saat yönünde döndürdüyseniz ve araba sola döndüyse, en azını söylemekten hayret duyarsınız. Bayiyi bir POS'u satmakla suçlayacaktınız ve yeni davranışın neden alıştığınızdan daha "iyi" olduğu veya bunun "belgelendirildiği" veya nasıl "ne kadar iyi olduğu nedenlerinden herhangi birini dinlemeniz muhtemel değildir. şeffaf "kontrol sistemidir. Bu yeni arabaya ve sürdüğünüz diğerlerine rağmen hala "otomobil" olmakla birlikte, bu arabayı sürerken, yeni arabayı başarılı bir şekilde sürmek için bir aracın nasıl sürülmesi gerektiği ile ilgili bazı temel kavramları değiştirmeniz gerekir. Bu genellikle kötü bir şeydir, ve bu sadece yeni paradigmaya karşı sezgisel bir avantaj olduğunda gerçekleşir. Belki de emniyet kemerlerinin eklenmesi iyi bir örnektir; 50 yıl önce yeni geldin ve gittin, ama şimdi kilitlemek zorundasın, sezgisel avantaj, kaza geçirirsen ön camdan veya yolcu koltuğuna gitmemeniz. O zaman bile, sürücüler direndi; Birçok araç sahibi, kullanımlarını zorunlu kılan yasalar kabul edilinceye kadar emniyet kemerlerini araçtan kesti.

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.