Gerçek dünya değerini temsil eden bir sabiti güncellemek Açık-Kapalı Prensibinin ihlali midir?


10

İşçilerin yıllık net gelirini hesaplayan bir sınıfım var. Vergi yüzdesini temsil eden bir sabiti vardır. Ancak bir gün vergi oranı değişti, bu yüzden kodu düzeltmem gerekiyor.

Bu sabiti düzeltme eylemi, bir sınıfın modifikasyona kapatılması gerektiğini varsaydığı için Açık-Kapalı Prensibinin ihlal edildiğine işaret ediyor mu?


10
Yazılım değişiyor çünkü gerçek dünya değişiyor. Öte yandan bir vergi yüzdesinin sabit hale getirilmesi Açık-Kapalı Prensibi'nin ihlali anlamına gelmez, çünkü sadece cahil bir şeydir. Vergi yüzdesi, çalışma zamanında bağlanması gereken bariz değiştirilebilir bir kalemdir.
Richard Chambers

4
Richard ile tamamen aynı fikirdeyim. Bu "sabiti" düzeltmek için kodu değiştirmeniz gerekiyorsa, OCP sorunlarınızın en azıdır.
Robert Harvey

3
OCP'nin ihlali oluşturan şey son derece özneldir ve her şey yine de biraz eskidir (çünkü uygulama mirası artık en iyi uygulama değildir). Bu, soruyu soran kişinin ne düşündüğünü tahmin etmeniz gereken tipik bir sorudur.
Robert Bräutigam

2
@DocBrown: "yeni bir gereklilik" ne oluşturur? Bana bazı kod göster, ben OCP bunu nasıl uygun olursa olsun, kesinlikle kod değiştirme gerektiren yeni gereksinimleri işaret edebilir. Yani soruya geri dönelim: Eğer geliştirici işletme uzmanına bu konuyu sorduysa ve vergi oranının her iki yılda bir defadan fazla değişmesi beklentisi yoksa, yapılandırılabilir veya enjekte edilebilir hale getirmenin bir anlamı yoktur. Basit tutun ve bildiklerinize hazırlanın . Ve bu şeyler için, elbette, onu sınıfın dışında yapın. Yani değişir .
Robert Bräutigam

1
@ RobertBräutigam: Demek istediğim, IMHO "OCP uygunluğu" diye bir şey yok, sadece "belirli gereksinimler kategorileri bağlamında OCP uygunluğu" var. Bir bileşenin hangi kategorilere "OCP uyumlu" olması gerektiği konusunda bazı öznellikler olabilir. Ancak bu soruda anlatıldığı gibi, anladığım gibi, değişen bir gereksinim zaten belirlendi, böylece bu "gelir hesaplama sınıfı" bu özel gereklilik bağlamında OCP'ye açıkça uymuyor.
Doc Brown

Yanıtlar:


14

OCP, B, C ve D kullanıcılarının kullanımı için bir tür kara kutu kütüphanesinde bir satıcı A tarafından sağlanan sınıfları veya bileşenleri düşünürken daha iyi anlaşılabilir (bunun netlik için kullandığım zihinsel bir model olduğunu unutmayın, gerçekte sınıfın tek kullanıcısının A'nın kendisi olması önemli değildir).

B, C ve D, sağlanan sınıfları kütüphanenin kaynak kodunda değişiklik yapmaya gerek kalmadan farklı kullanım durumları için kullanabilir veya yeniden kullanabilirse, bileşen OCP'yi ( bir kullanım durumu kategorisine göre) yerine getirir . Bunu başarmanın farklı yolları var,

  • sınıfı kalıtsal hale getirme (tipik olarak şablon yöntemi kalıbı veya strateji kalıbı ile birlikte)

  • bağımlılık enjeksiyonu için "enjeksiyon noktaları" sağlayarak

  • sınıf veya bileşen için yapılandırma parametreleri sağlayarak (örneğin, durumunuzda olduğu gibi "vergi yüzdesi" oluşturucu parametresine sahip olarak veya başka bir yapılandırma mekanizması kullanarak)

  • programlama diline veya ekosisteme bağlı olarak başka araçlar da olabilir

Ders kitaplarında bulacağınız tipik örnekler genellikle birinci veya ikinci türdür (sanırım çünkü bu kitabın yazarlarının gözünde üçüncü tür belirtilemeyecek kadar önemsizdir).

Gördüğünüz gibi, bunun, A koduyla ilgisi olmayan A sağlayıcısı (hata düzeltme, optimizasyon veya geriye dönük uyumlu bir şekilde yeni özellikler ekleme gibi) tarafından kaynak kodunda herhangi bir değişiklik yapılmasını yasaklamakla ilgisi yoktur. OCP, A'nın lib'deki bileşenlerin arayüzünü ve ayrıntı düzeyini nasıl tasarladığıyla ilgilidir, bu nedenle farklı yeniden kullanım senaryoları (farklı vergi oranlarına sahip resuage gibi) otomatik olarak değişiklik gereksinimlerini indüklemez.

Burada başkalarına söylenenlere rağmen, cevap açıkça "evet" dir , bu OCP'nin ihlali olacaktır.

EDIT: biri arasında tam olarak bu konu hakkında ayrıntılı bir blog yazısı yazmış görünüyor . Her ne kadar bazı bölümleri daha iyi ifade edilmiş olsa da (Derek Elkins'in işaret ettiği gibi) yazar genellikle "OCP'yi yerine getirmenin" mutlak bir özellik değil, sadece belirli bağlamlarda değerlendirilebilecek bir şey olduğu görüşünü paylaşıyor gibi görünüyor. gereksinim kategorileri.


Tamam, bu yüzden OCP, listelediğiniz üç yoldan biriyle farklı kullanım durumları için genişletilebilir davranış sağlamakla ilgili, değil mi? Peki ya bir OP örneği temel bir şeyin değişmek üzere olduğunu ima ederse? Ülke OP'sinin nereden geldiğini bilmiyorum, ancak ülkemde vergi oranı çok sık değişmeyen bir şey. Kötü bir örnekti, ama belki de bunu vurgulamak için kasıtlı olarak bir sabitte çıkarıldı. Yapılandırılabilir veya genişletilebilir olması gerektiğinden eminim. Belki de soru "A satıcısı tarafından kaynak kodunda herhangi bir değişiklik yapılmasını yasaklamakla ilgisi yoktur" kısmıyla ilgiliydi.
Vadim Samokhin

En azından ben bu şekilde anladım. Kabul edilen cevabını silen zavallı adam da sanırım. Biraz daha farklı bir açıdan gördünüz. Anladım ve katılıyorum. Ama en akıllıca yorum @Robert Bräutigam tarafından verildi gibi görünüyor. Şimdiye kadar OCP'nin öznel olduğunu fark etmedim.
Vadim Samokhin

1
Sanırım aynı soruyu sorduğumda, cevaplamam gereken bir soru var: "Bu davranış bir şekilde genişletilmeli veya yapılandırılmalı mı?" Evet ise - bir sınıfın doğrudan modifikasyonundan ziyade OCP ihlalidir. Eğer OCP'den başka bir şey yoksa bu durumda geçerli değildir.
Vadim Samokhin

1
@Zapadlo: Bir bileşen , bir sınıf gereksinimi için OCP'yi yerine getiriyorsa çok öznel değildir - çoğu durumda yeni bir gereksinimin bir bileşenin kaynak kodunda bir değişikliğe ihtiyacı varsa veya bileşen bu gereksinimi destekliyorsa, oldukça açıktır. ". Uygulamak için olası yaklaşımlar, listelediğim ilk 3 araçla sınırlı değildir, düzenlememe bakın. Öznellik fikriniz, OCP'nin yanıltıcı bir adı olduğu ve birçok ders kitabında açıklandığı için kötü olabilir.
Doc Brown

Öznellik fikrim, söylediklerini tam olarak anlamadığım gerçeğinden kaynaklandı - ama şimdi sanırım. Anlayışlı yorumlar ve cevabınız için çok teşekkürler.
Vadim Samokhin

4

Diğerlerinin söylediği gibi, ideal olarak işçi gelir sınıfı sabitin parametreleştirilmesine izin verecek ve bu sınıfı bu değerden bağımsız hale getirecektir.

Sonuçta, çağıran uygulama harici yapılandırma (örneğin bir dosya) açısından parametreleştirmeye de izin verebilir. Harici yapılandırmaya sahip olduktan sonra, vergi oranını değiştirebiliriz - ancak yapılandırma dosyası başlangıçta yalnızca bir kez okunursa, güncellenmiş vergi yüzdelerinin geçerli olması için uygulamanın yeniden başlatılması gerektiğini düşünün; zihin. Yapılandırmaya yönlendirildiğinde yapılandırmayı yeniden okumak için bir uygulama özelliği sağlayabiliriz veya yapılandırma dosyası değiştiğinde bunu fark eden daha karmaşık bir mekanizma sağlayabiliriz ...

Uzun vadede, vergi meselelerinin sadece bir yüzde daha fazlasını gerektirdiğini görebilirsiniz - örneğin, bir gün vergi yasaları daha karmaşıktır ve birkaç yüzde ve bazı sabitler gerektirir (ör.% X oranında vergilendirilen 10 bin doların altındaki miktar, kalanlar% Y olarak vergilendirilir).

Bu temel olarak, burada söz konusu ana sınıfın vergiyi hesaplamak için bir strateji nesnesini kabul ettiği bir strateji modeli kullanılmasını önermektedir.

Çeşitli stratejiler (ve% 's ve $ sabitleri) yapılandırma dosyasından seçilebilmelidir ve şimdi yeni bir strateji eklemek için bazı yeni kodların eklenmesi gerekir, ancak mevcut kodda güncellemeler olması gerekmez.

Her strateji, gerçek verginin nasıl hesaplanacağının yanı sıra kendi harici yapılandırma argümanlarının nasıl ayrıştırılacağını / yorumlanacağını bilebilir.

Dinamik olarak, vergi ayrıca yönetilen yerel ayara da bağlı olabilir, bu nedenle kazançlarla veya çalışanlarla (veya her ikisiyle) ilişkilendirilmiş yerel ayara sahip olabilirsiniz. Harici yapılandırmada, yerel ayarları vergi stratejisiyle ilişkilendirebiliriz.


Ayrıca , bunları açıkça yönettiğimiz bağımlılık enjeksiyonuna bakın .


1
Soru, koddaki vergi yüzdesi gibi bir şeyi gömmek için kötü bir fikir değilse, eminim ki burada çoğumuz (OP dahil). Soru şuydu: "Bu OCP'yi ihlal ediyor mu?" Bu yüzden cevabınızın bu soruya nasıl atıfta bulunduğunu göremiyorum.
Doc Brown

1

Vergi değerini değiştirmek için sınıfı değiştirmeniz gerekiyorsa, tasarımı gerçekten OCP'yi ihlal ediyor. Şimdiye kadar tanımladığınız şey için uygun tasarım, hesap makinesi sınıfının vergi değerini parametre olarak almasıdır.

Sınıfınız örneklenmişse (statik bir sınıf olmadığı anlamına gelirse), değeri kurucu aracılığıyla enjekte edilen vergi değişkeni sınıf özelliğini yaparak sınıf uyumunu da geliştirirsiniz.

Kısacası, mevcut tasarımınız sınıfınızı gerçekten sabit olmayan sabit bir değere bağımlı hale getirir (sabit, PI değeri gibi, ne olursa olsun asla değişmeyecek bir değer olarak tanımlanır). OCP'yi ihlal ediyor. Vergi değerini yapıcı bağımsız değişkeni olarak alacak şekilde tasarımı değiştirin.


0

Tamamen @Becuzz ile katılıyorum ve sadece bunu özetlemek istiyorum: OCP, bir sınıfa enjekte edilen tekrar kullanılan (dolayısıyla yararlı) soyutlamaları bulmakla ilgilidir. Sınıfın davranışı, kodunu değiştirerek değil, farklı uygulamalar sağlayarak değiştirilir. Bu, Robert Martin'in " Çevik Yazılım Geliştirme, İlkeler, Desenler ve Uygulamalar " kitabında kristal açıklığa kavuşturuldu , ilgili "Açık-kapalı prensibi", "Soyutlama Anahtardır" alt bölümünü kontrol edin. Davranışın sadece kalıtımla değiştirilebileceği başka bir yanlış kanıtı açıklığa kavuşturur. 1988 yılında Robert Martin değil, “ Nesne Odaklı Yazılım İnşaatı ” kitabında öneren Bertrand Meyer'di .


-2

Gördüğüm gibi açık kapalı prensibin ihlali değil. Bununla birlikte, zaman içinde değişmek zorunda olan bir şeyin (vergi yüzdesi gibi) bir sabit olması bir tasarım hatasıdır: sabitin değerini değiştirmemeli, vergi yüzdesini nasıl ele aldığınız. Bu, her şeyi yeniden derlemeden değiştirilebilen bir tür ayar olmalıdır.


"Tasarım kusuru" sabit değiştirmek için kodu yeniden derlemek gerekir gibi açık kapalı prensibi ihlal olduğunu?
Erdrik Ironrose
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.