Açık / Kapalı Prensibi Netleştirin


25

Açıkladığım gibi, açık / kapalı prensip bir kez yazılı kodun değiştirilmemesi gerektiğini (hata düzeltmeleri dışında) belirtir. Ancak işletme kurallarım değişirse, bu değişiklikleri uygulayan kodu değiştirmemeli miyim? Bana prensip olarak bir şey anlamadığımdan şüpheleniyorum çünkü bu bana mantıklı gelmiyor.

Yanıtlar:


22

Bu muhtemelen açıklanması en katı prensiplerden biridir. İzin ver deneyeyim. Mükemmel çalışan ve hiçbir hata bulunmayan bir Fatura sınıfı yazdığınızı hayal edin. Bir faturanın PDF'sini yapar.

Sonra birisi, içinde bağlantı bulunan bir HTML faturası istediklerini söylüyor. Bu isteği yerine getirmek için Faturada hiçbir kodu değiştiremezsiniz. Bunun yerine, şimdi istediklerini yapan başka bir sınıf HTMLInvoice yaparsınız. Mirastan yararlanırsınız, böylece HTMLInvoice'da pek çok yinelenen kod yazmak zorunda kalmazsınız.

Eski Faturayı kullanan eski kod bozuk veya hiçbir şekilde etkilenmiyor. Yeni kod HTMLInvoice'i kullanabilir. (Ayrıca , katı L sınıfı olan Liskov Yerine koyma özelliğini de yaparsanız , HTMLInvoice örneklerini, Fatura örneklerini bekleyen mevcut koda verebilirsiniz.) Herkes sonsuza dek mutlu bir şekilde yaşıyor.

Fatura değişikliğe kapalı, uzatma için açık. Ve bunun işe yaraması için Faturayı önceden düzgün bir şekilde yazmak zorundasınız,


1
Eğer işletme kuralları değişirse, hiçbir hata olmadan kusursuz çalışma varsayımı olmaz, bu yüzden aç / kapat prensibi geçerli olmaz?
JeffO,

Ben bu kuralla kendim mücadele ettim ve Kate'in önerdiği şey temelde bu konuda karar verdiğim şeydi. İş dünyasında, daha küçük, daha esnek sınıfları programlamaya çalışırsınız, böylece onları yeniden kullanabilirsiniz. Doğru çalışmalarını sağladıysanız, değiştirmek istemezsiniz. Ancak nadiren tamamen "yapılır", bu yüzden bazı değişiklikler kaçınılmazdır. Metnin nesne değil, "modül" dediğini unutmayın. OCP'yi işlev seviyesinde sık sık başarılı bir şekilde uyguluyorum, bir şeyi mükemmel yapan ve hiçbir zaman değiştirmesi gerekmeyen sıkı işlevler var.
CodexArcanum

1
@Jeff OI, bir hatanın düzeltilmesi (kodun orijinal gereksinimi karşılamadığı ve hiç kimse olduğu gibi istemediği) ve gereksinimleri değiştirme arasında ayrım yapar. PDF'lere ihtiyacım varsa ve kod PDF'leri yaparsa, şimdi HTML (ve genellikle insanlar da yerine HTML de istemektedir) olsa bile hata olmaz.
Kate Gregory

2
@Winston - Faturayı düzgün yazman gerektiğini söylediğimde demek istediğim buydu. İdeal olarak, zaten oldukça soyut bir fatura vardı ve siz bunu bekleyen PDFInvoice'i miras aldınız. Olmazsa, gelecekte kurallara aykırı davranmaya karar vermek için kuralı bir kere çiğnemelisiniz. Her iki durumda da gelecekteki değişiklikleri önceden tahmin etmek tüm bunların büyük bir bölümünü oluşturuyor - ve bu da tarifin "bir fili yakala ve kes" kısmı.
Kate Gregory,

1
Son ifaden en önemlisi. Açık / kapalı bir tasarım idealdir - ve bunu başarabilmek için tasarıma önden bakmalısınız. Her şey de açık / kapalı olarak tatmin etmek zorunda değildir, ancak oraya gidebilirseniz güçlü bir araçtır.
Alex Feinman 12:13

13

Okuduğunuz Open-Kapalı Prensibi ObjectMentor de Bob Amcanın arkadaşı tarafından makalesine? Bence orada daha iyi açıklamalardan biri.

Nesneye yönelik tasarımla ilgili birçok sezgisel tarama vardır. Örneğin, “tüm üye değişkenleri özel olmalı” veya “global değişkenlerden kaçınılmalıdır” veya “çalışma zamanı tür tanımlamasını kullanmak (RTTI) tehlikelidir”. Bu sezgisel taramaların kaynağı nedir? Onları gerçek kılan ne? Onlar mı hep doğrudur? Bu sütun, bu sezgisel araştırmanın altında yatan tasarım ilkesini - açık-kapalı prensibi - inceler.

Ivar Jacobson'ın dediği gibi: “Tüm sistemler yaşam döngüleri boyunca değişir. İlk versiyondan daha uzun sürmesi beklenen sistemler geliştirilirken bu akılda tutulmalıdır. ”Değişim karşısında kararlı olan ve ilk versiyondan daha uzun sürecek tasarımları nasıl oluşturabiliriz? Bertrand Meyer, 1988'de, şimdiye kadar ünlü açık-kapalı prensibini icat ettiği zaman bize rehberlik etti. Onu felç etmek için:

YAZILIM GİRİŞLERİ (SINIFLAR, MODÜLLER, FONKSİYONLAR, VB.) UZATMA AÇILMALI, DEĞİŞTİRME İÇİN KAPALI OLMALIDIR.

Bir programda yapılan tek bir değişiklik, bağımlı modüllerde bir değişiklik basamağıyla sonuçlandığında, bu program “kötü” tasarımla ilişkilendirdiğimiz istenmeyen nitelikleri gösterir. Program kırılgan, katı, öngörülemez ve tekrar kullanılamaz hale geliyor. Açık-kapalı ilke, buna çok basit bir şekilde saldırır. Asla değişmeyen modüller tasarlamanız gerektiğini söylüyor . Gereksinimler değiştiğinde, zaten çalışan eski kodu değiştirerek değil, yeni kod ekleyerek bu tür modüllerin davranışını genişletirsiniz.

Açıklama

Açık-kapalı prensibe uygun olan modüller iki temel özelliğe sahiptir.

  1. Onlar “Uzantıya Açık” tır.
    Bu, modülün davranışının uzatılabileceği anlamına gelir. Modülün, uygulamanın gereksinimleri değiştikçe yeni ve farklı şekillerde davranmasını sağlayabilir veya yeni uygulamaların gereksinimlerini karşılayabiliriz.
  2. Onlar “Değişikliğe Kapalı”.
    Böyle bir modülün kaynak kodu inviolate. Hiç kimse kaynak kodu üzerinde değişiklik yapamaz.

Bu iki özelliğin birbiriyle çelişkili olduğu görülüyor. Bir modülün davranışını genişletmenin normal yolu, o modülde değişiklik yapmaktır. Değiştirilemeyen bir modülün normal olarak sabit bir davranışı olduğu düşünülmektedir. Bu iki karşıt nitelik nasıl çözülebilir?

Soyutlama Anahtardır ...


3
Bu, soyutlamayı açıklayan iyi bir makale. Dikkate alınması gereken temel bir nokta var ve bu ilk başta ortaya konan iyi bir soyut tasarım mıydı? Pek çok dükkanın pek çok eski kodu var, onu değiştirmenin tek yolu "uzatma" değil "değişiklik". Eğer durum buysa, muhtemelen bunu değiştirmek için çalışılmalıdır, ancak bunu yapana kadar, kod değiştirme zorunluluğunuzda kalırsınız.
Michael K,

@Chris, cool - Eğer böyle bir şey isterseniz Bob Amca tarafından "Temiz kod" kitabını da öneririm.
Martijn Verburg

@Michael - Tamamen katılıyorum, neredeyse test edilebilir bir hale getirmek için kodu yeniden düzenlemek zorunda kalmak gibi.
Martijn Verburg

Makale soyutlamanın önemini çok güzel gösteriyor. Fakat soyutlamalar arasındaki bağlantıyı kavramıyorum ve onları yazdıktan sonra asla modülleri değiştirmeye çalışmıyorum. Soyutlama, X modülünü Y modülünde değişiklik yapmadan değiştirebildiğim anlamına geliyor, ancak gerekmesi halinde X modülünü veya Y modülünü değiştirebileceğim anlamına gelmiyor mu?
Winston Ewert

1
Vay. Kod inviolate mi? Ben asla Bob Amca'nın büyük hayranı olmadım. Bu prensip bilgiçlik taslayan, son derece pragmatik olmayan ve gerçeklikle sınırlı bir bağlantısı var.
user949300,

12

Kate Gregory tarafından cevap çok iyidir, ama yeni bir gereklilik mevcut nispeten küçük değişiklikle tatmin edilebilir farklı bir durum düşünün Invoicesınıfta. Örneğin, Fatura PDF'sine yeni bir alanın eklenmesi gerektiğini varsayalım. OCP'ye göre, yeni alan mevcut uygulamada birkaç kod satırı değiştirilerek eklenebilse bile yeni bir alt sınıf oluşturmalıyız.

Anladığım kadarıyla OCP, projelerin çoğu zaman sürüm kontrolünü kullanmadığı, 90'ların ve 90'ların başındaki gerçeğini yansıtıyor, daha az otomatik regresyon testleri veya karmaşık yeniden düzenleme araçlarının yararı vardı. OCP, manuel olarak test edilip üretime sokulan kod kırma riskinden kaçınmaya çalıştı. Bugün, çalışan yazılımların kırılma riskini yönetmek için daha iyi yollarımız var (yani sürüm kontrol sistemleri, TDD ve otomatik test ve yeniden düzenleme araçları).


2
Evet, çünkü pratikte, tüm yöntemleri korumalı yapmadıkça (O / C'den çok daha önemsiz olan YAGNI ilkesini berbat eden ve aynı zamanda ihlal eden), olası tüm geleceklere uygun bir sınıf oluşturmak mümkün değildir. dito).
Martin Wickman 12:13

"OCP'ye göre, yeni alan mevcut uygulamada birkaç kod satırı değiştirilerek eklenebilse bile, yine de yeni bir alt sınıf oluşturmalıyız.": Gerçekten mi? Neden yeni alanlar veya yeni yöntemler eklemiyorsunuz? Önemli olan nokta, yalnızca eklediğiniz (genişleten) ve zaten olanı değiştirmemenizdir.
Giorgio

Bence standart kütüphaneler / çerçeveler ile uğraşırken ilke mantıklı geliyor. İyi tanımlanmış kod parçalarını açmak ve değiştirmek istemezsiniz. Aksi halde hepsi sürekli refactoring ve test, test, test ile ilgilidir.
mastaBlasta 12:14

@Giorgio Tabii, yeni alanlar veya yöntemleri ekleyerek olduğu ben çoğu durumda, ne öneriyoruz. Ama bu uzatma değil , "değişiklik"; OCP'nin tüm amacı, "uzantı için açık" olurken kodun "değişiklik için kapalı" olması (yani önceden var olan kaynak dosyada değişiklik olmaması) olması gerektiğidir; ve OCP'de uzatma, uygulama devralma yoluyla sağlanır.
Rogério

@ Rogério: Sınıf düzeyinde uzatma ve değişiklik arasındaki sınırı neden tanımlarsınız? Bunun özel bir nedeni var mı? Bunu yöntem düzeyinde ayarlamayı tercih ederim: Bir yöntemi değiştirmek, uygulamanızın davranışını değiştirir, (genel) bir yöntem eklemek, arabirimini genişletir.
Giorgio

6

Şahsen ben bu ilkenin bir tutam tuzla alınması gerektiğini düşünüyorum. Kod organiktir, işletmeler zaman geçtikçe değişir ve bir işletmenin ihtiyaçlarına göre kod değişir.

Soyutlamanın anahtar olduğu konusunda kafamı karıştırmak çok zor. Ya soyutlama başlangıçta yanlıştıysa? İşletme işlevi önemli ölçüde değiştiyse ne olur?

Bu prensip esasen, bir tasarımın ORİJİNAL niyetlerinin ve davranışlarının asla değişmemesini sağlar. Bu muhtemelen herkese açık API'leri olanlar ve müşterileri için yeni sürümlere ve diğer bazı yeni durumlara ayak uydurmakta zorlanıyor. Ancak, bir şirketin TÜM koduna sahip olması durumunda, bu ilkeye itiraz ediyorum.

Kodunuzun iyi test kapsamına sahip olması, kod tabanınızı yeniden düzenlemeyi bir esinti yapmalıdır. İşlerin yanlış gitmesi tamam demektir - testleriniz daha iyi bir tasarım için size rehberlik edecektir.

Söylemek gerekirse, herhangi bir test yoksa, o zaman bu ilke sağlamdı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.