Neden birçok yazılım geliştirici açık / kapalı prensibini ihlal ediyor?


74

Neden birçok yazılım geliştiricisi, yükseltme işleminden sonra uygulamayı kıracak yeniden adlandırma işlevleri gibi birçok şeyi değiştirerek açık / kapalı prensibini ihlal ediyor ?

Bu soru React kütüphanesindeki hızlı ve sürekli versiyonlardan sonra kafama atlıyor .

Her kısa dönemde sözdiziminde, bileşen adlarında, vb.

React'in gelecek sürümündeki örnek :

Yeni İtiraz Uyarıları

En büyük değişiklik, React.PropTypes ve React.createClass'ı kendi paketlerine çıkarmamızdır. Her ikisine de ana React nesnesi üzerinden erişilebilir, ancak her ikisinin de kullanılması, geliştirme modundayken konsola bir kerelik kullanım dışı bırakma uyarısı kaydedecektir. Bu, gelecekteki kod boyutu optimizasyonlarını mümkün kılacaktır.

Bu uyarılar uygulamanızın davranışını etkilemeyecektir. Ancak, özellikle console.error işlevini bir başarısızlık olarak değerlendiren bir test çerçevesi kullanıyorsanız, bazı sıkıntılara yol açabileceklerini biliyoruz.


  • Bu değişiklikler bu ilkenin ihlali olarak değerlendiriliyor mu?
  • React gibi bir şeye yeni başlayan biri olarak, kütüphanedeki bu hızlı değişikliklerle nasıl öğrenirim (çok sinir bozucu)?

6
Bu açıkça onu gözlemlemenin bir örneğidir ve 'çok fazla' iddianız yetersizdir. Lucene ve RichFaces projeleri ünlü örneklerdir ve Windows COMM port API'sıdır, ancak başkalarını düşünemiyorum. Ve React gerçekten 'büyük bir yazılım geliştiricisi' midir?
user207421,

62
Herhangi bir ilke gibi, OCP'nin de değeri vardır. Ancak, geliştiricilerin sonsuz öngörmeleri olmasını gerektirir. Gerçek dünyada, insanlar genellikle ilk tasarımlarını yanlış yaparlar. Zaman geçtikçe, bazıları uyumluluk uğruna eski hataları etrafında çalışmayı tercih ederken, diğerleri sonunda kompakt ve yüksüz bir kod temeli olması adına onları temizlemeyi tercih ediyor.
Theodoros Chatzigiannakis

1
En son ne zaman bir nesneye yönelik dili "başlangıçta amaçlandığı gibi" gördünüz? Temel prensip, sistemin her kısmının herkes tarafından sınırsızca genişletilebileceği anlamına gelen bir mesajlaşma sistemi idi . Şimdi bunu tipik OOP benzeri dilinizle karşılaştırın - kaç tane mevcut bir yöntemi dışarıdan genişletmenize izin veriyor? Kaç kişi faydalı olabileceğini yeterince kolaylaştırıyor?
Luaan

Miras berbat. 30 yıllık tecrübe, mirası tamamen terk etmeniz ve her zaman yeni bir başlangıç yapmanız gerektiğini göstermiştir . Bugün herkesin her yerde her zaman bağlantısı var, bu yüzden miras bugün sadece tamamen anlamsız. Nihai örnek "Windows'a karşı Mac" idi. Microsoft geleneksel olarak "mirası desteklemeye" çalıştı, bunu birçok yönden görüyorsunuz. Apple, eski kullanıcılara her zaman "F- - - Siz" demiştir. (Bu, dillerden cihazlara ve işletim sistemlerine kadar her şey için geçerlidir.) Aslında, Apple tamamen doğruydu ve MSFT tamamen yanlış, sade ve basitti.
Fattie

4
Çünkü gerçek hayatta zamanın% 100'ünü çalıştıran tamamen sıfır "ilkeler" ve "tasarım desenleri" var.
Matti Virkkunen

Yanıtlar:


148

IMHO JacquesB'nin cevabı, çok fazla doğruluk içermesine rağmen, OCP'nin temel bir yanlış anlaşıldığını gösterir. Adil olmak gerekirse, sorunuz zaten bu yanlış anlaşılmayı ifade ediyor - işlevleri yeniden adlandırma , geriye dönük uyumluluğu bozuyor , ancak OCP'yi bozmuyor. Uyumsuzluk kırılması gerekli görünüyorsa (veya uyumsuzluğu kırmamak için aynı bileşenin iki versiyonunu koruyorsanız), OCP daha önce kırılmıştı!

Jörg W Mittag'ın yorumlarında daha önce de belirtildiği gibi, ilke “bir bileşenin davranışını değiştiremezsiniz” demez - kişi, arıların yeniden kullanımı için (ya da uzatılmış olarak) açık olacak şekilde tasarım yapmaya çalışmalıdır . çeşitli şekillerde, değişiklik yapmadan . Bu, doğru "uzatma noktaları" sağlayarak ya da @AntP tarafından "belirtildiği gibi", her doğal uzatma noktasının varsayılan olarak bulunduğu noktaya bir sınıf / işlev yapısının ayrıştırılmasıyla yapılabilir. " OCP’yi izleyen IMHO’nun “eski sürümü geriye dönük uyumluluk için değişmeden tutmak” ile hiçbir ortak yanı yok ! Veya, @ DerekElkin adlı kullanıcının yorumu aşağıdadır:

OCP bir modülün nasıl yazılacağına dair bir tavsiye [...], hiçbir zaman modüllerin değişmesine izin vermeyen bir değişim yönetimi sürecinin uygulanması ile ilgili değildir.

İyi programcılar deneyimlerini, "doğru" uzatma noktaları göz önünde bulundurarak (veya daha da iyisi - yapay uzatma noktalarına gerek kalmayacak şekilde) tasarlamada kullanırlar. Ancak, bunu doğru bir şekilde ve gereksiz yere aşırı mühendislik yapmadan yapmak için, bileşeninizin gelecekteki kullanım durumlarının nasıl görünebileceğini önceden bilmeniz gerekir. Deneyimli programcılar bile geleceğe bakamaz ve yaklaşmakta olan tüm gereksinimleri önceden bilir. Ve bu nedenle bazen geriye dönük uyumluluk ihlal edilmek zorundadır - bileşeninizin kaç uzatma noktasına sahip olduğu veya belirli gereksinimler için OCP'yi ne kadar iyi takip ettiği önemli değil, her zaman kolayca değiştirilmeden uygulanamayan bir gereksinim olacaktır. bileşen.


14
IMO, OCP'yi “ihlal etmenin” en büyük nedeni, ona uygun şekilde uymak için çok çaba sarf etmesidir. Eric Lippert, .NET Framework sınıflarının çoğunun OCP'yi neden ihlal ettiği konusunda mükemmel bir blog yazısına sahiptir .
BJ Myers,

2
@ BJMyers: bağlantı için teşekkürler. Jon Skeet'in, korunan varyasyon fikrine çok benzeyen arı olarak OCP hakkında mükemmel bir görevi var.
Doktor Brown,

8
BU! OCP, dokunulmadan değiştirilebilecek bir kod yazmanız gerektiğini söylüyor! Neden? Bu yüzden sadece bir kez test etmeniz, gözden geçirmeniz ve derlemeniz gerekir. Yeni davranış yeni koddan gelmelidir. Kanıtlanmış eski kodu girerek değil. Yeniden yapılanmaya ne dersiniz? Refactoring iyi bir OCP ihlalidir! Bu nedenle, varsayımlarınız değiştiğinde kodunuzu yeniden düşüneceğinizi düşünerek kod yazmak günahtır. Hayır! Her varsayımı kendi küçük kutusuna koyun. Yanlış olduğunda kutuyu tamir etmeyin. Yeni bir tane yaz. Neden? Çünkü eskisine geri dönmen gerekebilir. Sen yaparsan, hala işe yararsa iyi olurdu.
candied_orange

7
@CandiedOrange: Yorumunuz için teşekkürler. Refactoring ve OCP'yi tanımladığınız kadar ters görmüyorum. OCP'yi takip eden bileşenleri yazmak için çoğu zaman birkaç yeniden düzenleme döngüsü gerekir. Amaç, gereksinimlerin tamamını "ailesini" çözmek için değişiklik gerektirmeyen bir bileşen olmalıdır. Bununla birlikte, kişi, “tam olarak” üzerinde bulunan ve fazla çalıştırmaya çok kolay giden bir bileşene keyfi uzatma noktaları eklememelidir. Yeniden yapılanma olasılığına güvenmek, birçok durumda buna daha iyi bir alternatif olabilir.
Doc Brown

4
Bu cevap, şu anda en iyi yanıtta bulunan hataları söylemek iyi bir iş çıkardı - Bence açık / kapalı olsa da başarılı olmanın en önemli yanı , "uzatma noktaları" açısından düşünmeyi bırakmak ve her doğal uzatma noktasının varsayılan olarak bulunduğu noktaya sınıf / işlev yapısı. "Dışarıdan içeri" nin programlanması, bunu başarmanın çok iyi bir yoludur; mevcut yöntem / fonksiyonunuzun sunduğu her senaryo, dekoratörler, adaptörler vb. İçin doğal bir uzama noktası oluşturan harici bir arayüze gönderilir
Ant P

67

Açık / kapalı prensibinin faydaları vardır, ancak bazı ciddi dezavantajları da vardır.

Teoride , prensip geriye doğru uyumluluk problemini "uzatma için açık fakat değişiklik için kapalı" olan bir kod oluşturarak çözer. Bir sınıfın bazı yeni gereksinimleri varsa, sınıfın kaynak kodunu hiçbir zaman değiştirmezsiniz, bunun yerine davranışı değiştirmek için gerekli olan uygun üyeleri geçersiz kılan bir alt sınıf oluşturur. Bu nedenle, sınıfın orijinal versiyonuna karşı yazılan tüm kodlar etkilenmez, bu nedenle yaptığınız değişikliğin mevcut kodu bozmadığından emin olabilirsiniz.

Gerçekte kolayca kod şişirilmesi ve eski sınıfların kafa karıştırıcı karmaşası ile bitirdiniz. Bir bileşenin bazı davranışlarını uzantı yoluyla değiştirmek mümkün değilse, bileşenin yeni bir türevini istenen davranışla belirtmeniz ve eski sürümü geriye dönük uyumluluk için değişmeden tutmanız gerekir.

Diyelim ki, birçok sınıfın devraldığı temel sınıfta temel bir tasarım hatası keşfedeceksiniz. Hatanın yanlış türde özel bir alandan kaynaklandığını söyleyin. Bir üyeyi geçersiz kılarak bunu düzeltemezsiniz. Temel olarak, tüm sınıfı geçersiz kılmanız gerekiyor, bu da Objectalternatif bir temel sınıf sağlamak için genişletmek zorunda kalacağınız anlamına geliyor - ve şimdi de tüm alt sınıflara alternatifler sağlamanız gerekiyor, böylece bir kopyalanmış nesne hiyerarşisi, bir hiyerarşi kusurlu, biri gelişmiş olacak . Ancak hatalı hiyerarşiyi kaldıramazsınız (çünkü kodun silinmesi değişikliktir), gelecekteki tüm istemciler her iki hiyerarşiye de maruz kalır.

Şimdi bu sorunun teorik cevabı "sadece ilk defa doğru tasarla" dır. Kod kusursuz bir şekilde çözülürse, herhangi bir kusur veya hata olmadan ve olası tüm gelecekteki gereksinim değişiklikleri için hazırlanmış uzatma noktaları ile tasarlandıysa, karışıklığı önlersiniz. Fakat gerçekte herkes hata yapar ve hiç kimse geleceği mükemmel şekilde tahmin edemez.

.NET framework gibi bir şey alın - hala jenerikler on yıldan daha önce tanıtılmadan önce tasarlanan koleksiyon sınıfları kümesini taşıyor. Bu kesinlikle geriye dönük uyumluluk için bir nimettir (herhangi bir şeyi yeniden yazmak zorunda kalmadan çerçeveyi yükseltebilirsiniz), ancak aynı zamanda çerçeveyi şişirir ve geliştiricilere pek çoğunun eski olduğu birçok seçenek sunar.

Görünüşe göre React geliştiricileri, açık / kapalı prensibini sıkı bir şekilde takip etmenin karmaşıklık ve kod boşluğundaki maliyete değmeyeceğini düşünüyorlardı.

Açık / kapalı için pragmatik bir alternatif kontrollü amortismandır. Tek bir sürümde geriye dönük uyumluluk yerine, eski bileşenler bir sürüm döngüsü için tutulur, ancak müşterilere derleyici uyarıları ile eski yaklaşımın daha sonraki sürümlerde kaldırılacağı konusunda bilgi verilir. Bu, müşterilere kodu değiştirme zamanı verir. Bu, bu durumda Tepki yaklaşımı gibi görünüyor.

(İlkeyi yorumlamam, Robert C. Martin'in Açık-Kapalı Prensibine dayanmaktadır )


37
“İlke temel olarak bir bileşenin davranışını değiştiremeyeceğinizi söylüyor. Bunun yerine, bileşenin yeni bir türevini istenen davranışla donatmanız ve eski sürümü geriye dönük uyumluluk için değişmeden tutmanız gerekiyor.” - Buna katılmıyorum. İlke, bileşenleri davranışını değiştirmek gerekmeyecek şekilde tasarlamanız gerektiğini söyler, çünkü istediğiniz şeyi yapmak için genişletebilirsiniz. Sorun şu ki, bunun nasıl yapıldığını henüz çözemedik, özellikle şu anda geniş kullanımda olan dillerle. İfade Sorunu bir parçası…
Jörg W Mittag

8
… Örneğin. Ne Java ne de C♯ İfade için bir çözüme sahip değildir. Haskell ve Scala yaparlar, ancak kullanıcı tabanları çok daha küçüktür.
Jörg W Mittag

1
@ Giorgio: Haskell'de çözüm tip sınıflarıdır. Scala'da çözüm dolaylı ve nesnelidir. Üzgünüz, şu anda elinizde bağlantı yok. Evet, multimetodlar (aslında, onların "çoklu" olmaları gerekmez, bunun yerine Lisp'in gerekli olan yöntemlerinin "açık" niteliği vardır) de olası bir çözümdür. Tipik kağıtları yazar anda var olan tüm çözümler geçersiz hale gerçeği ile sonuçlanan ifade soruna bir kısıtlama ekler şekilde yazılır çünkü ifade problemin birden ifadeler, olduğunu unutmayın, o zaman nasıl kendi gösteriyor ...
Jörg W Mittag

1
… Dil bu "zor" versiyonunu bile çözebilir. Örneğin, Wadler ilk olarak ifade sorununu sadece modüler uzatma ile ilgili değil, aynı zamanda statik olarak güvenli modüler uzatma için de ifade etti. Genel Lisp multimethods ancak statik olarak güvenli değildir , sadece dinamik olarak güvenlidir. Odersky daha sonra modüler olarak güvenli olması gerektiğini söyleyerek bunu daha da güçlendirdi, yani güvenlik, tüm programa bakmadan, sadece genişletme modülüne bakarak statik olarak kontrol edilebilir olmalıdır. Bu aslında Haskell tipi sınıflarla yapılamaz, ancak Scala ile yapılabilir. And in the…
Jörg W Mittag

2
@ Giorgio: Kesinlikle. Common Lisp multimetods'u EP'yi çözen şey aslında çoklu gönderim değildir. Yöntemlerin açık olduğu gerçektir. Tipik FP'de (veya prosedürel programlamada), tür ayrımcılığı işlevlere bağlanır. Tipik OO'da, yöntemler türlere bağlanır. Ortak Lisp yöntemleri açıktır , bunlar gerçeklerden sonra ve farklı bir modülde sınıflara eklenebilir. EP'yi çözmek için onları kullanışlı kılan özellik budur. Örneğin, Clojure'nin protokolleri tek bir gönderimdir, ancak aynı zamanda EP'yi de (statik güvenlik konusunda ısrar etmediğiniz sürece) çözer.
Jörg W Mittag

20

Açık / kapalı prensibi ideal olarak adlandırırdım. Tüm idealler gibi, yazılım geliştirmenin gerçeklerine de az önem verir. Ayrıca, tüm idealler gibi, pratikte de onu elde etmek imkansızdır - kişi bu ideale mümkün olan en iyi şekilde yaklaşmaya çalışır.

Hikayenin diğer tarafı Altın Kelepçe olarak bilinir. Altın Kelepçeler, kendinizi açık / kapalı prensibine çok fazla köle ettiğiniz zaman elde ettiğiniz şeydir. Altın Kelepçeler, geriye doğru hiç bir zaman geriye doğru uyumsuzluğu bozmayan ürününüzün büyümesi nedeniyle gerçekleşen bir şey değildir, çünkü çok fazla geçmiş hata yapılmıştır.

Bunun ünlü bir örneği, Windows 95 bellek yöneticisinde bulunur. Windows 95 pazarlamasının bir parçası olarak, tüm Windows 3.1 uygulamalarının Windows 95'te çalışacağı belirtildi. Microsoft, Windows 95'te test etmek için binlerce program için lisans aldı. Sorunlu durumlardan biri Sim City idi. Sim City aslında ayrılmamış belleğe yazmaya neden olan bir hataydı. Windows 3.1, "uygun" bir bellek yöneticisi olmadan, bu küçük bir sahte pas oldu. Ancak, Windows 95'te, bellek yöneticisi bunu yakalar ve bir segmentasyon hatasına neden olur. Çözüm? Windows 95'te, eğer uygulama adınız buysa simcity.exe, işletim sistemi segmentasyon hatasını önlemek için bellek yöneticisinin kısıtlarını gerçekten gevşetir!

Bu idealin ardındaki asıl mesele, ürün ve hizmetlerin ortak kavramlarıdır. Kimse gerçekten birini ya da diğerini yapmaz. Her şey, ikisi arasındaki gri bölgede bir yere diziliyor. Ürün odaklı bir yaklaşımdan düşünüyorsanız, sesleri açmak / kapatmak harika bir ideal gibi. Ürünleriniz güvenilir. Ancak, hizmetlere gelince, hikaye değişiyor. Açık / kapalı prensibiyle, ekibinizin desteklemesi gereken fonksiyonelliğin sonsuzluğa asimptotik olarak yaklaşması gerektiğini göstermek kolaydır , çünkü eski işlevselliği asla temizleyemezsiniz. Bu, geliştirme ekibinizin her yıl daha fazla kodu desteklemesi gerektiği anlamına gelir. Sonunda kırılma noktasına ulaşırsın.

Günümüzde çoğu yazılım, özellikle de açık kaynak, açık / kapalı ilkenin ortak rahat bir versiyonunu izler. Açık / kapalı durumunun küçük sürümler için slavca takip edildiğini, ancak büyük sürümler için terk edildiğini görmek çok yaygındır. Örneğin, Python 2.7, Python 2.0 ve 2.1 günlerinde birçok "kötü seçenek" içeriyor, ancak Python 3.0 hepsini silip süpürdü. (Ayrıca, Windows 2000 yayınlandı Windows NT kod tabanına Windows 95 kod tabanı vardiya her türlü şeyi kırdı ama vermedi biz davranışlarını karar vermek uygulamanın adını kontrol bellek yöneticisi ile uğraşmak zorunda asla demek!)


SimCity hakkında çok güzel bir hikaye. Kaynağınız var mı?
BJ Myers,

5
@BJMyers Eski bir hikaye, Joel Spoleky bu makalenin sonuna değindi . Başlangıçta yıllar önce video oyunları geliştirmekle ilgili bir kitabın parçası olarak okudum.
Cort Ammon

1
@BJMyers: Onlarca popüler uygulama için "hack" ile benzer bir uyumluluğa sahip olduklarından eminim.
Doktor Brown,

3
@BJMyers, Raymond Chen'in The Old New Thing bloguna iyi bir şekilde okumak isterseniz , Geçmiş etiketine göz atın veya "uyumluluk" için bir arama yapın. Yukarıda belirtilen SimCity davasına dikkat çekecek kadar yakın olan bir şey de dahil olmak üzere çok sayıda masal hatırlanıyor - Addentum: Chen isimleri suçlamak istemiyor.
Theraot

2
95-> NT geçişinde bile çok az şey kırıldı. Orijinal Windows için SimCity hala Windows 10'da (32-bit) harika çalışıyor. Konsol oyunlarının sesi düzgün işlemesini sağlamak için DOS oyunları bile sesi kapatmanız veya VDMSound gibi bir şey kullanmanız durumunda mükemmel çalışıyor. Microsoft uyumluluğu çok ciddiye alıyor ve herhangi bir "sanal makineye koyalım" kısayollarını da almıyorlar. Bazen bir geçici çözüme ihtiyaç duyar, ancak bu özellikle göreceli olarak oldukça etkileyicidir.
Luaan

11

Doc Brown'ın cevabı kesinliğe en yakın olan diğer cevaplar ise Açık Kapalı Prensip'in yanlış anlamalarını göstermektedir.

Açıkça yanlış anlamayı ifade etmek için, OCP geriye doğru uyumsuz bir değişiklik yapmaması gerektiğini anlamına geldiğini bir inanç var gibi görünüyor (hatta veya herhangi bu satırlar boyunca değişimler gibi bir şey.) OCP Eğer kalmamak bileşenleri tasarımı bekleniyor ihtiyaç için Bu değişikliklerin geriye dönük olarak uyumlu olup olmadığına bakılmaksızın, işlevlerini genişletmek için bunlarda değişiklikler yapın. İşlevselliği eklemenin yanı sıra, bir bileşende geriye dönük uyumlu (ör. Yeniden düzenleme veya optimizasyon) veya geriye dönük olarak uyumsuz (ör. İşlevselliği kullanımdan kaldırma ve kaldırma) gibi değişiklikler yapmanıza neden olabilecek birçok neden vardır. Bu değişiklikleri yapabileceğiniz, bileşeninizin OCP'yi ihlal ettiği anlamına gelmez (ve kesinlikle sizin OCP'yi ihlal ediyorlar).

Gerçekten, kaynak koduyla ilgili değil. OCP'nin daha soyut ve alakalı bir ifadesi şudur: "bir bileşen, soyutlama sınırlarını ihlal etmeden uzamaya izin vermelidir". Daha ileri gideceğim ve daha modern bir yorumlamanın şöyle olduğunu söyleyeceğim: "bir bileşen soyutlama sınırlarını zorlamalı , ancak uzamayı sağlamalıdır". Bob Martin’in OCP’deki makalesinde bile “kaynak kodunu istilacı” olarak ““ değiştirmeye kapalı ”olarak nitelendirdiği“ makalesinde bile ”, daha sonra kaynak kodunu değiştirmeyle ve soyutlama ile ilgisi olmayan kapsülleme hakkında konuşmaya başlar. sınırları.

Bu nedenle, sorudaki hatalı öncül, OCP'nin bir kod tabanının gelişmesiyle ilgili bir kılavuz olduğu yönündedir. OCP tipik olarak “bir bileşen uzantılara açık ve tüketicilerin değişikliklerine kapalı olmalıdır” şeklinde sloganlaştırılır. Temel olarak, bir bileşenin tüketicisi , bileşene işlevsellik eklemek isterse , eski bileşeni, ek işlevsellik ile yenisine genişletebilmelidir, ancak eski bileşeni değiştirememelidir .

OCP , bir bileşenin yaratıcısı hakkında işlevselliği değiştiren veya kaldıran hiçbir şey söylemez . OCP, bugüne dek hata uyumluluğunu korumayı savunmuyor . Yaratıcı olarak, bir bileşeni değiştirerek veya kaldırarak OCP'yi ihlal etmiyorsunuz. Siz veya daha doğrusu yazdığınız bileşenler OCP'yi ihlal ediyor, eğer tüketicilerin bileşenlerinize işlevsellik ekleyebilmeleri için tek yol mutasyona sokmak, örneğin maymun eklemesi yapmak.veya kaynak koda erişme ve yeniden derleme. Çoğu durumda, bunların hiçbiri tüketici için seçenek değildir; bu, bileşeniniz "uzatma için açık" değilse, şanssız kalmaz. Onlar sadece bileşeninizi ihtiyaçları için kullanamazlar. OCP, kütüphanenizin tüketicilerini en azından tanımlanabilir bir “uzantı sınıfı” ile ilgili olarak bu pozisyona koymadığını savunuyor. Kaynak kodda veya kaynak kodun birincil kopyasında bile değişiklikler yapılabilse bile, bunu yapmanın birçok olası olumsuz sonucu olduğu için, onu değiştiremeyeceğinizi "iddia etmek" en iyisidir.

Yani sorularınızı cevaplamak için: Hayır, bunlar OCP'nin ihlali değildir. Bir yazarın yaptığı hiçbir değişiklik OCP'yi ihlal edemez çünkü OCP bir değişiklik oranı değildir. Değişiklikler, olabilir oluşturmak OCP ihlallerini ve bunlar kod temeli önceki sürümlerinde OCP başarısızlıkları motive edilebilir. OCP, bir kod tabanının evrimsel tarihi değil, belirli bir kod parçasının özelliğidir.

Bunun tersine, geriye dönük uyumluluk bir kod değişikliğinin bir özelliğidir . Bir kod parçasının geriye dönük olarak uyumlu olduğunu veya uyumlu olmadığını söylemenin bir anlamı yoktur. Sadece bazı kodların eski kodlara göre geriye dönük uyumluluğu hakkında konuşmak mantıklıdır . Bu nedenle, bazı kodların geriye doğru uyumlu olup olmadıklarının ilk kesilmesinden bahsetmek hiç mantıklı gelmiyor. İlk kod kesimi, OCP'yi tatmin edebilir veya yerine getiremez veya genel olarak bazı kodların, OCP'yi kodun herhangi bir tarihsel sürümüne atıfta bulunmadan yerine getirip getirmediğini belirleyebiliriz.

Son sorunuza gelince, genellikle genel olarak görüşe dayalı olarak StackExchange'in tartışmaya açık bir konudur, ancak kısaca tanımladığınız olgunun JavaScript yorgunluğu olarak adlandırıldığı teknik ve özellikle JavaScript'e açıktır . ( Bazıları hicivli, başka bakış açılarından bahseden, başka çeşitli makaleler bulmak için google'ı kullanmaktan çekinmeyin .)


3
“Yaratıcı olarak, bir bileşeni değiştirerek veya kaldırarak OCP'yi ihlal etmiyorsunuz.” - bunun için bir referans verebilir misiniz? Gördüğüm ilkenin tanımlarından hiçbiri "yaratan" ın (ne demekse) prensipten muaf olduğunu belirtmez. Yayınlanan bir bileşeni kaldırmak açıkça bir değişikliktir.
JacquesB

1
@JacquesB İnsanlar ve hatta kod değişiklikleri OCP'yi ihlal etmez, bileşenler (yani gerçek kod parçaları) yapar. (Ve açıkça söylemek gerekirse, bu, bileşenin, başka bir bileşenin OCP'sini ihlal ettiği değil, OCP'ye uymadığı anlamına gelir.) Cevabımın asıl amacı, OCP'nin kod değişikliklerinden bahsetmemesidir. , kırma veya başka türlü. Bir bileşen ya uzantıya açık ya da modifikasyona kapalı ya da bir yöntem olabilir privateya da olmayabilir gibi değildir. Bir yazar ileride bir privateyöntem uygularsa public, bu erişim kontrolünü ihlal ettiği anlamına gelmez, (1/2)
Derek Elkins

2
... ve bu yöntemin daha privateönce olmadığı anlamına da gelmez . "Yayınlanmış bir bileşeni kaldırmak açıkça bir değişikliktir", sıra dışı bir şey. Yeni sürümün bileşenleri OCP'yi karşılar ya da istemezler, bunu belirlemek için kod tabanının geçmişine ihtiyacınız yoktur. Mantığınıza göre, hiçbir zaman OCP'yi karşılayan bir kod yazamam. Geriye dönük uyumluluk, bir kod değiştirme özelliği, OCP ile bir kod özelliği arasındaki ilişkiyi kapatıyorsunuz. Yorumunuz, quicksort'un geriye dönük olarak uyumlu olmadığını söylemek kadar mantıklı. (2/2)
Derek Elkins

3
@JacquesB İlk önce, bunun OCP'ye uygun bir modül hakkında konuştuğunu tekrar not edin . OCP, bir modülün nasıl yazılacağına dair bir tavsiyedir, böylece kaynak kodun değiştirilemeyeceği kısıtı göz önüne alındığında , modül genişletilebilir. Gazetede daha önce , hiç bir zaman değişmeyen modüller tasarlamaktan bahsediyor , hiçbir zaman modüllerin değişmesine izin vermeyen bir değişim yönetimi süreci uygulamaktan bahsediyor. Cevabınıza düzenlemeye bakarak, modülün kodunu değiştirerek "OCP'yi bozmayın". Bunun yerine, eğer "genişletmek" modül kaynak kodunu değiştirmenizi gerektiriyorsa , (1/3)
Derek Elkins

2
“OCP, bir kod tabanının evrimsel tarihi değil, belirli bir kod parçasının özelliğidir.” - mükemmel!
Doc Brown
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.