“Her şeyi Onar” tasarım deseni nedir?


74

Linuxdevcenter.com adresindeki Stephen Figgins'in bu 2003 makalesinde Bram Cohen'in BitTorrent'i "Her şeyi Onar" tasarım desenini kullanarak tanımlanmıştır.

Her ikisinin de BitTorrent'i kavramasını zorlaştıran, ancak çalışmaya layık görülen daha az yaygın bir yaklaşım, Cohen'in bağımsızlığı kullanmasıdır. Bir işlem, bir defadan fazla uygulandığında önemsizdir, başka bir değişikliğe neden olmaz. Cohen, “Her Şeyi Düzelt” olarak adlandırdığı bir tasarım deseni kullandığını ve neyin değişebileceğini gerçekten fark etmeden bir dizi değişikliğe tepki verebilecek bir işlev kullandığını söylüyor. “Gerçekleşen olayı not edin, sonra bu çok iddiasız şekilde yazılmış her şeyi düzeltme işlevini çağırın ve ne olup bittiğini temizler ve sıfırdan yeniden hesaplar” diye açıklıyor. Fakirlik, bazı zor hesaplamaları kolaylaştırırken, işleri biraz sarsılmış hale getirir. Eğer bir çağrının, bir çağrının neyi değiştireceği her zaman net değildir. Önceden bilmek zorunda değilsin. Fonksiyonu çağırmakta özgürsünüz,

Bu yüzünde oldukça hoş geliyor.

Bununla birlikte, belirsiz bir "her şeyi düzelt" işlevinin çağrılmasının, sistemin sağlamlığını verimlilik maliyetinde artıracağını ve içerdiği sistemi (dikkatlice planlayan ve yürüten işlemleri tercih edebilecek olan) potansiyel olarak berbat edeceğini düşünüyorum.

Yine de daha önce kullandığımı söyleyemem. Ayrıca başvurusunun kaynağını çevrimiçi olarak bulamıyorum (ancak , buna dayandığını iddia eden bir tane buldum .). Ayrıca, bu makalenin dışına referans bulamıyorum (ve google- fu'mın oldukça iyi olduğunu düşünüyorum) ancak SOApatterns.org sitesinde "Idempotent Capability" için bir Idempotent Capability " için bir giriş buldum .

Bu fikir başka bir adla daha iyi bilinir mi?

"Her şeyi Onar" tasarım deseni nedir? Artıları ve eksileri neler?


4
İsmin, aynı zamanda, bir fonksiyonun sabit noktası fikrine bir referans olduğundan şüpheliyim, x = f (x). Ne olursa olsun uygulamak kaç kez f için , x , sonuç aynıdır. Doğru sonucu elde ettiğinizde, doğru sonucu tekrar işlemek aynı doğru sonucu verir.
9000

7
Herkesin istediği herhangi birşeye herhangi bir isim verebileceğini ancak bunun iyi bilinen bir yazılım deseni yapmadığını unutmayın. Özgürlük, başlı başına iyi bilinen bir kavramdır; sadece burada yaratıcı olarak kullanılıyor gibi görünüyor.
Robert Harvey

1
Bu bana Ana Olay Döngüsünün Mac OS'de nasıl uygulandığını hatırlatıyor. Herhangi bir olaya yanıt veren tek bir işlevdi ve genellikle tüm kontrollerin durumunu test etmek ve tüm UI'yi gerektiği gibi güncellemek için yapılandırıldı. Idempotent, gerçekten.
Lucas,

3
This sounds quite nice on the face of it. Gerçekten mi? Bana korkunç geliyor!
Michael

3
@Michael Paket yöneticilerini sevmiyor musun? Aynı konseptte çalışırlar, daha küçük bir ölçekte: Sistemin nasıl görünmesini istediğinizi işaretleyin, "her şeyi düzeltin" i çalıştırın, uygun şekilde kurar / kaldırır / yükseltir, ancak yalnızca değişiklikler olsaydı yapacak bir şeyleri olur.
Izkata

Yanıtlar:


100

Diyelim ki oldukça karmaşık bir HTML sayfanız var - bir açılır menüde bir şey seçerseniz, başka bir kontrol görünebilir veya üçüncü kontroldeki değerler değişebilir. Buna yaklaşmanın iki yolu var:

  1. Her denetim için, bu denetimdeki olaylara yanıt veren ve diğer denetimleri gereken şekilde güncelleyen ayrı bir işleyici yazın.

  2. Sayfadaki tüm kontrollerin durumuna bakan ve her şeyi düzelten tek bir işleyici yazın .

İkinci çağrı "idempotent" çünkü tekrar tekrar arayabilirsin ve kontroller her zaman doğru şekilde düzenlenecek. Oysa ilk çağrılar, bir çağrı kaybolduğunda veya tekrarlanırsa, örneğin işleyicilerden biri bir geçiş yaparsa, sorunları olabilir.

İkinci çağrı için mantık biraz daha belirsiz olurdu, ama sadece bir işleyici yazmanız yeterli.

Ve her iki çözümü de kullanabilirsiniz, "her şeyi düzelt" işlevini gerektiği gibi "sadece güvenli tarafta olmak" olarak adlandırabilirsiniz.

İkinci yaklaşım, durum farklı kaynaklardan geldiğinde, örneğin sunucudan oluşturulan kullanıcı girişi veya farklı kaynaklardan geldiğinde özellikle iyidir. ASP.NET'te, teknik geri bildirim kavramıyla çok iyi oynar çünkü sayfayı her oluşturduğunuzda her şeyi düzelt fonksiyonunu çalıştırırsınız.

Şimdi olayların kaybedildiğini veya tekrarlandığını ve farklı kaynaklardan durum aldıklarını belirttiğime göre, bu yaklaşımın BitTorrent'inki gibi sorunlu bir alana nasıl iyi bir şekilde eşleştiğinin açık olduğunu düşünüyorum.

Eksileri? Açıkça anlaşılır olan, performans artışı olduğu için her zaman her şeyi gözden geçirmek daha az etkilidir. Ancak BitTorrent gibi bir çözüm ölçeklendirmek için değil ölçeklendirmek için optimize edilmiştir, bu yüzden bu tür şeyler için iyidir. Çözmeye çalıştığınız soruna bağlı olarak, bu sizin için uygun olmayabilir.


9
Bana öyle geliyor ki, MVC “Her şeyi Onar” ın tipik bir örneği: modeli değiştirdiğinizde ve görünümü sıfırdan yeniden çizdiğinizde, eylemin potansiyel olarak hangi parçaları etkileyebileceğini ilaca teşebbüs etmeden manzara tamamen yeniden çiziliyor.
Matthieu M.

3
Bu esas olarak Saltstack, Ansible ve Nix gibi sistemlerin arkasındaki ilke gibi geliyor. Bir konfigürasyonun açıklaması verildiğinde, çeşitli farklı sistemleri aynı son duruma teorik olarak getirebilirsiniz.
kojiro

1
@MatthieuM. Ön uç gelişiminde oldukça popüler olan React , sanal dom farklılaşması dışında, gerçek dom ile yalnızca gerçek değişiklikleri güncellediğini düşünüyor
Izkata

2
@ Izkata Tepki bile daha, bu cevap bana Redux hakkında düşündürdü.
Kevin,

2
"Her şeyi düzeltmek" ve belirsiz olanın farklı şeyler olduğunu belirtmek faydalı olabilir: "her şeyi düzeltmek" genellikle önemsizdir (ancak olması gerekmez) ve kesin işlemlerin her şeyi düzeltmesi, hatta performansı olması gerekmez ceza - sadece iki kez yapıldığında aynı sonucu verin.
Hans-Peter Störr

15

Makalenin biraz eski olduğunu düşünüyorum, çünkü okuduğumda bu hiç alışılmadık ya da yeni bir fikir değil. Bu fikir, gerçekten basit bir Gözlemci uygulaması olduğunda, ayrı bir model olarak sunulmaktadır. O sırada ne yaptığımı tekrar düşündüğümde, birbirine bağlı veri içeren bir dizi farklı panelle karmaşık bir arayüzün arkasında oturmak için mantık üzerinde çalıştığımı hatırlıyorum. Kullanıcı değerleri değiştirebilir ve / veya bir optimizasyon yordamı çalıştırabilir ve bu eylemlere dayanarak, kullanıcı arayüzünün dinleyeceği ve gerektiği gibi güncelleyeceği olaylar oluşturuldu. Geliştirme sırasında bazı panellerin gerektiği zaman güncellenmemesi gereken bir takım sorunlar vardı. Düzeltme (tasarımın içinde kalmak) diğer olaylardan olayları oluşturmaktı. Sonuçta, o zamanlar her şey yolunda gidiyordu. hemen hemen her değişiklik tüm panellerin yenilenmesine neden oldu. Belirli bir panelin yenilenmesi gerektiğinde yalıtılmaya çalışılmasının tüm karmaşıklığı boşa çıkmıştı. Ve zaten önemli değildi. Etkili bir erken optimizasyon oldu. Hepsini yenilediği tek bir olaya katlayarak, zamandan ve emekten tasarruf edecektim.

Her şeyi düzeltmek ya da her şeyi yenilemek için tasarlanmış sayısız sistem var. Bir satır ekleyen / güncelleyen ve ardından DB isteğinde bulunan tüm CRUD arayüzlerini düşünün. Bu egzotik bir yaklaşım değil, sadece akıllıca olmayan bir çözüm. Bunun 2003 yılında 'desen ateşinin' yüksekliği olduğunu anlamalısınız. Söyleyebileceğim kadarıyla, insanlar yeni kalıpları isimlendirmenin şöhret ve zenginliklere giden yolu olacağını düşündü. Beni yanlış anlama, bir kalıp kavramının soyuttaki çözümleri tanımlamak için son derece yararlı olduğunu düşünüyorum. İşler biraz raydan çıktı. Talihsizdir çünkü genel olarak kalıp kavramı hakkında çok fazla alaycılık yarattı. Sadece bu bağlamda, bunun hakkında 'geleneksel olmayan' bir çözüm olarak konuşmanın anlamı var. O' ORM'ler veya DI kapları etrafındaki ortodoksiye benzer. Bu araçları kullanmadan çok önce insanlar yazılım geliştirmiş olsalar bile çoğu zaman bu araçlar fazla kullanılmaz olsa da, onları kullanmama alışılmadık bir durum olarak görülüyor.

Yani 'her şeyi düzeltmek' için geri dönelim. Basit bir örnek, hesaplama aracıdır. Basit çözüm sayıları toplamak ve değerlerin önem derecesine göre bölmektir. Bir numara ekler veya değiştirirseniz, en baştan tekrar yapın. Toplamı ve sayı sayısını takip edebilirsiniz ve birisi bir sayı eklediğinde, sayımı artırıp toplamı ekleyin. Şimdi tekrar tüm sayıları eklemiyorsunuz. Excel ile bir aralığa başvuran ve o aralıktaki tek bir değeri değiştiren bir formülle daha önce çalıştıysanız, 'her şeyi düzelt' desenine bir örneğiniz vardır, yani o aralığa referansı olan herhangi bir formül, ne olursa olsun yeniden hesaplanacaktır. bu değer alakalıydı (örneğin, sumif () gibi bir şey kullanarak).

Bu, bunun belirli bir bağlamda akıllıca bir seçim olmadığı anlamına gelmez. Bu örnekte, şimdi güncellemeleri desteklememiz gerektiğini varsayalım. Şimdi eski değeri bir şekilde bilmem ve toplamı yalnızca delta ile değiştirmem gerekiyor. Bunların hiçbiri, bunu dağınık ya da eşzamanlı bir ortamda yapmayı denemeyi düşünene kadar gerçekten zor değil. Artık her türlü sıkıntılı zamanlama sorunuyla başa çıkmak zorundasınız ve muhtemelen yeniden hesaplamadan çok daha fazlasını yavaşlatan önemli bir tıkanıklık yaratmanız gerekecek.

Buradaki sonuç, 'her şeyi düzeltmek' veya 'her şeyi yenilemek' yaklaşımının doğru olması çok daha kolay olmasıdır. Daha sofistike bir yaklaşımın çalışmasını sağlayabilirsiniz, ancak bu çok daha karmaşık ve bu nedenle kusurlu olma ihtimali daha fazla. Ayrıca birçok bağlamda, 'her şeyi yenile' yaklaşımı daha verimli olabilir. Örneğin, yazma yaklaşımlarındaki kopya, tek iş parçacıklı yaklaşımlar için genellikle daha yavaştır, ancak yüksek eşzamanlılık olduğunda, kilitlerden kaçınmanıza izin verebilir ve bu nedenle daha iyi performans sağlayabilir. Diğer durumlarda, değişiklikleri etkili bir şekilde bir araya getirmenize izin verebilir. Bu yüzden çoğu sorun için, neden yapamayacağınız konusunda özel bir nedeniniz yoksa ve ihtiyaç duyduğunuzda daha karmaşık bir şey yapmaktan endişe duymuyorsanız, muhtemelen her şeyi yenileyen bir yaklaşımla başlamak istersiniz.


2
Excel'in yalnızca değişikliklere bağlı hücreleri yeniden hesaplamak istediğinden eminim, bu yüzden tüm hücreleri yeniden hesaplamak için tetiklemenin bir yolu var: superuser.com/questions/448376/… (sanırım "her şeyi düzelt" olur) )
Aaron Hall

@AaronHall Eğer öyleyse, gerçekten kötü bir uygulama. Örn: 60.000 hücreyi hesaplamak için düzenli olarak 15-30 dakika boyunca 7 işlemcinin% 100'ünü tükettiğini izliyorum. Hesaplamalar karmaşık değil. Genellikle Python'u başlatmak da dahil olmak üzere birkaç saniye içinde sayfadaki her şeyi yapabilen Python programları yazdım. Bu nasıl bu kadar uzun sürdüğü konusundaki en iyi tahminimdi. Sanırım başka bir şey olabilir. Ayrıca, Excel'de bu özelliğin nedeni olabilecek çok sayıda eski hata vardır.
JimmyJames

1
@AaronHall, bu kullanıcıyla otomatik hesaplamanın sayfada devre dışı bırakılması da mümkündür. Bunu genellikle büyük çalışma kitaplarında yapıyorum çünkü her girdiğimde 15 dakikam yok.
JimmyJames

@AaronHall Ben biraz daha düşündüm ve bir noktaya var. Varsayımlarım muhtemelen aşırı geniş. Bana daha çok güvendiğim bir şeye odaklanmış olan cevabı güncelledim.
JimmyJames

2
@JimmyJames: Yapmak istediğim nokta, en iyi yaklaşımın koşullara bağlı olarak çok fazla değişiklik gösterebileceği ve "her şeyi düzelt" in "her bir değişiklikte her şeyi hevesle düzeltmek" ve "tüm değişiklikler tamamlandıktan sonra her şeyi tembel bir şekilde düzeltmek" şeklinde bölünmesi olabilir. ".
supercat

4

Bunun bir "tasarım deseni" olduğundan emin değilim, ancak bu tür davranışları Kukla, Aşçı veya Powershell DSC damarında, son durum yapılandırması veya istenen durum yapılandırması olarak sınıflandırırdım .

Bu çözümler tipik olarak, sorunun açıklandığı gibi bir iş mantığı düzeyinde değil, sistem yönetimi düzeyinde çalışır, ancak bu aynı şekilde etkili bir paradigmadır ve bu tür araçlar genellikle doğada açıklayıcı olsa da, aynı prensipler prosedür kodlarında veya komut dosyalarında uygulanabilir.


1

Bunu daha çok kullanıcı arayüzlerinde kullandım. Güzel olan şey, bir kez yazmanız ve en basitinden en zor duruma kadar her şeyi eşit derecede iyi idare etmesidir (örneğin, kullanıcı ekranı döndürürse veya kullanıcı bir pencereyi yeniden boyutlandırdığında dizüstü bilgisayarda / masaüstünde ve neredeyse her şey değişir) ).

Verimlilik konusunda endişelenmek için pek bir neden yok. Kullanıcı arayüzünde, pahalı şeyler taşınan öğeyi yeniden çizmek gibi şeylerdir. Her bir öğenin nereye gittiğinin ve ne kadar büyük olduğunun hesaplanması genellikle oldukça hızlıdır. Emin olmanız gereken tek şey, bir öğenin tam olarak ait olduğu yerde kalması gerektiğinde, onu taşımak için herhangi bir kod yürütülmemesidir. Gerçek değişiklikler, yine de yapmanız gereken şeyler.


0

Reaktif programlama ilkelerine benziyor. "Her şeyi düzelt" mevcut bir "çekirdek" duruma bakar ve etkilenmesi gereken her şeyi ("bilgisayarlı devletler") yayar. Bu türetmeyi optimize ederseniz, yüksek verime ulaşabilir, a-la React, eğer saf bir şekilde yapılırsa, yine de yeterince hızlı olabilse de, optimum olmayabilir.

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.