Kalıtım için tasarım ekstra maliyete nasıl yol açabilir? [kapalı]


12

Bu yüzden bir csharpsealed class in miras almak istedim ve yandı. Kaynağa erişiminiz yoksa onu açmanın hiçbir yolu yoktur.

Sonra bana "neden sealedvar bile?" Diye düşündürdü . 4 ay önce. Bu konuda birçok şey okumasına rağmen anlayamadım:

O zamandan beri hepsini sindirmeye çalıştım, ama bu benim için çok fazla. Sonunda dün tekrar denedim. Hepsini tekrar taradım, birkaç tane daha:

Sonunda, çok fazla düşünmeden sonra , orijinal başlığı yeni başlığa dayanarak ağır bir şekilde düzenlemeye karar verdim .

Eski bir soru çok geniş ve sübjektif idi. Temel olarak şunu soruyordu:

  1. Eski başlıkta: Mühürlü kullanmak için iyi bir sebep
  2. Vücutta: Mühürlü bir sınıf nasıl düzgün bir şekilde değiştirilir? Miras hakkını unuttun mu? Kompozisyon mu kullanıyorsunuz?

Ama şimdi, (ki dün yapmadığım) her şeyin mirasını önlediğini anlamak ve gerçekten miras üzerinde kompozisyon kullanabiliriz ve kullanmalıyız , ihtiyacım olanın pratik örnekler olduğunu fark ettim .sealed

Sanırım burada sorum, BayMindor'un bana bir sohbette bana önerdiği şey (ve aslında her zaman olmuştur) : Kalıtım için tasarım nasıl ekstra maliyete neden olabilir?


5
Soru oldukça agresif bir şekilde ifade ediliyor ve bir rant gibi geliyor. Alakalı ve objektif cevaplar istiyorsanız tekrar yazmalısınız.
Euphoric

11
Bkz Çerçeve Classes So Many Mühürlü edilmektedir Neden? Eric Lippert tarafından. Sınıfları mühürlemek için birkaç iyi neden sunar.
Robert Harvey

9
O zaman makaleyi okumadın. Geri dön ve tekrar oku. Şuna dayanır: Bir müşterinin sınıfınızı genişleterek kırabileceği sayısız yolu tahmin edemezsiniz. Bunun için müşterilerinizi suçlayabilirsiniz, ancak onları desteklemek zorunda kalacaksınız.
Robert Harvey

4
@Cawas Bağladığı veya ayrıntılı olarak açıkladığı makaleyi okuyabilir veya okuyabilirsiniz. Bu makaleyi yorumuyla özetliyordu.
Servy

7
Üzgünüm, ama ben burada koşan ben değilim. Sorunuzun cevabı çok basit: mirası desteklemek istemediğinizde bir sınıfı mühürleyin. Bu kadar.
Robert Harvey

Yanıtlar:


27

Bunu anlamak o kadar zor değil. sealedMicrosoft için özel olarak hayatlarını kolaylaştırmak, tonlarca tasarruf sağlamak ve itibarlarına yardımcı olmak için yaratılmıştır. Bir dil özelliği olduğu için herkes bunu da kullanabilir, ancak muhtemelen hiçbir zaman mühürlü kullanmanız gerekmeyecektir.

Çoğu insan bir sınıfı genişletememekten şikayet eder ve eğer yaparlarsa, herkesin doğru çalışmasını sağlamanın geliştiricilerin sorumluluğu olduğunu bildiğini söylerler. Bu doğru, ancak aynı insanların Windows tarihi hakkında hiçbir ipucu yok ve sorunlardan sealedbiri çözmeye çalışıyorum hariç .

Bir geliştiricinin .Net çekirdek sınıfını genişlettiğini varsayalım (çünkü mühürlü yoktu) ve mükemmel bir şekilde çalışmasını sağladık. Yay, geliştirici için. Geliştirici ürünü müşteriye teslim eder. Geliştiricinin uygulaması harika çalışıyor. Müşteri mutlu. Hayat güzel.

Microsoft artık bu belirli .Net çekirdek sınıfındaki hataları gidermeyi içeren yeni bir işletim sistemi yayınladı. Müşteri zamana ayak uydurmak istiyor ve yeni işletim sistemini kurmayı seçiyor. Birdenbire, müşterinin çok sevdiği uygulama artık çalışmıyor, çünkü .Net çekirdek sınıfında düzeltilen hataları hesaba katmadı.

Suçu kim alıyor?

Microsoft'un tarihine aşina olanlar, Microsoft'un yeni işletim sisteminin, Windows kütüphanelerini yanlış kullanan uygulama yazılımını değil, suçu alacağını biliyor. Bu nedenle, sorunu yaratan uygulama şirketi yerine sorunu düzeltmek Microsoft'ta görev alır. Windows kodunun şişirilmesinin nedenlerinden biri de budur. Okuduğum kadarıyla, Windows işletim sistemi kodu, belirli bir if-then ile belirli bir uygulamanın ve sürümün çalışıp çalışmadığını kontrol eder ve eğer öyleyse, programın çalışmasına izin vermek için bazı özel işlemler yapar. Bu, Microsoft'un başka bir şirketin yetersizliğini gidermek için harcadığı çok para.

Kullanmak sealedyukarıdaki senaryoyu tamamen ortadan kaldırmaz, ancak yardımcı olur.


4
@Cawas Onu kötüye kullanmak oldukça zor. Eric Lippert, birçok kez, yöntemlerin olduğu gibi, sınıfların, sealedözel olarak mühürlenmedikçe, varsayılan olarak, sadece çok az sınıfın miras alınacak şekilde tasarlandığından, varsayılan olarak olmasını istediğini belirtmiştir . Sınıfınızın onu desteklemek için inşa edilmemesi çok daha muhtemeldir ve eğer onu mühürsüz olarak işaretlemek için yolunuzdan çıkarsanız, bu geliştirici zamanı geçirdiğinizden emin olmalısınız.
Servy

1
Eğer insanlar iç geliştirme yazılımları için mühürlü kullanıyorlarsa, muhtemelen yanlış kullanıyorlar ya da çok mükemmel olmaya çalışan şirket zamanını boşa harcıyorlar. Muhtemelen söylüyorum, çünkü her zaman belirli bir senaryoda mantıklı gelebilecek durumlar vardır. Ancak, kütüphane tipi yazılım geliştirenler için, Microsoft'un buna ihtiyaç duyduğuna karar vermesinin aynı nedenleri için çok yararlı olduğundan şüphelenirim.
Dunk

2
@Cawas Çoğu geliştirici tarafından yazılan sınıfların büyük çoğunluğunun kalıtsal olarak desteklenmesi gerekmez ve kalıtımın desteklenmesi için yazılmaz. Bu, kod yazarak okuyuculara / kullanıcılara hızlı ve etkili bir şekilde aktarılabilir sealed. Aslında varsayılan seçenek olsaydı, o zaman birisi bir türden miras alırsa, onu desteklemek için inşa edildiğini bilirdi.
Servy

2
Bir sınıfı açığa çıkarmak, sınıfın onu desteklemek için kurulduğu anlamına gelmez. Bu sadece birisinin sınıftan miras almak ve onu açmak istediğini gösterir. En iyi durumda, mühürlü kullanmak, geliştiricilerin mevcut işlevselliği (mühürlü sınıfa eşdeğer) yeniden yazmasına neden olur, ancak daha sık olmamakla birlikte, kaynak kodu mevcutsa, herhangi bir sonuç dikkate alınmadan onu açacaktır. Özel olarak ve nadiren mühürlenmiş olmak daha iyidir, çünkü geliştirici bu sınıfın neden mühürlendiğini bulmak isteyebilir . Çok fazla kapalı sınıf var ve nedenini umursamıyorlar.
Dunk

1
Ayrıca güvenlik kullanmak için bir sebeptir! Bir dosyaya erişmeye çalışan korumalı bir uygulamayı düşünün. Korumalı alan, dosya adı dizelerini test edebilir, ancak bir saldırgan size bir değişken gönderebilirse Stringve güvenlik kontrolünden sonra ancak G / Ç'den önce değiştirirse ne olur? Senaryo tür Java neden Stringişaretlenir final(benzer sealed) olduğuna inanıyorum ve aynı mantık bazı C # kararları dayanır bahis.
Darien

23

sealedsınıf yazarının onu miras almak üzere tasarlamadığını belirtmek için kullanılır. Ne az, ne fazla.

Bir arabirimin uygun şekilde tasarlanması birçok programcı için yeterince zordur. Potansiyel olarak miras alınabilecek bir sınıfın uygun şekilde tasarlanması zorluk ve kod satırları ekler. Yazılan daha fazla kod satırı, daha fazla kodun korunması anlamına gelir. Artan bu zorluktan kaçınmak sealediçin, sınıfın asla miras alınmayı amaçlanmadığını gösterebilir ve bu bağlamda, bir sınıfı mühürlemek bir sorun için mükemmel geçerli bir çözümdür .

Sınıfın CustomBoeing787türetildiği vakayı düşünün Airliner. Bu, CustomBoeing787bazı korunan yöntemleri geçersiz kılar Airliner, ancak hepsinden değil. Geliştiricinin yeterli zamanı varsa ve buna değerse, geçersiz kılınan yöntemler çağrıldığında bile (örneğin nesnenin durumunu değiştiren korumalı ayarlayıcılar) bir bağlamda her şeyin beklendiği gibi çalışmasını sağlamak için sınıfı test edebilir. Aynı geliştiricinin (1) zamanı yoksa, (2) patronu / müşterisi için ek yüzlerce veya binlerce dolar harcamak istemiyorsa veya (3) sahip olmadığı ek kod yazmak istemiyorsa şu anda ihtiyacı var (YAGNI), o zaman yapabilir:

  • ya bu kodu daha sonra potansiyel hataları açıklamak için bu projeyi sürdürecek olan programcıların endişesi göz önüne alındığında, vahşi doğada olduğu gibi bırakın,

  • ya da sınıfı sealedgelecekteki programcılara bu sınıfın kalıtsal olarak tasarlanmadığını ve onu mühürlemenin ve bir ebeveyn olarak kullanmanın kendi sorumluluğunuzda olduğunu açıkça gösterecek şekilde işaretleyin .

Mümkün olduğunca çok veya mümkün olduğunca az sayıda sınıfı mühürlemek iyi bir fikir mi? Deneyimlerime göre, kesin bir cevap yok. Bazı geliştiriciler sealedçok fazla kullanma eğilimindedir ; diğerleri sınıfın nasıl miras alınacağı ve bunun neden olabileceği sorun umurumda değil. Böyle bir kullanım göz önüne alındığında, sorun programcıların girinti için iki veya dört boşluk kullanıp kullanmayacaklarını belirlemeye yarayan soruna benzer: doğru cevap yoktur.


Tamam ... Tekrar agresif geliyorsam özür dilerim, ama burada sadece açık ve iddialı olmak istiyorum ... Ne yazdığınızı sadece 2 yoldan biriyle yazabilirim, eğer tl;drburaya yazacak olsaydınız . Ya "Hayır, tek bir iyi sebep yok" ya da "Bence iyi bir neden yok, ama ben de bilmiyorum." . Bana göre "kesin bir cevap yok" da bunlardan biri.
cregox

6
sealedsınıf yazarının onu miras almak üzere tasarlamadığını belirtmek için kullanılır. Bu senin tek iyi nedenin.
Robert Harvey

Bu size ışıksız bir bisiklet vermek ve zorlamak için iyi bir neden, bir şekilde ışık ekleyemezsiniz.
cregox

2
@Cawas Nasıl yani? Bu bağlamda bisiklete bir ışık yok olmasını sağlamak için bisiklet üreticisi için önemli değil, ama genellikle olan bir tür kullanıcı uygulaması, belirli bir tam uygulama olduğundan emin olmak için önemlidir. İhtiyacınız olan kısıtlamaları uygularsınız. Bazı durumlarda insanlar gerçekten gerekli olmayan bir kısıtlama ekleyebilir; buna bir örnek verdiniz. Kısıtlamanın tek bir yerde yanlış kullanılması, hiçbir şeyi asla kısıtlamamanız gerektiği anlamına gelmez.
Servy

1
Ayrıca güvenlik kullanmak için bir sebeptir! Bir dosyaya erişmeye çalışan korumalı bir uygulamayı düşünün. Korumalı alan, dosya adı dizelerini test edebilir, ancak bir saldırgan size bir değişken gönderebilirse Stringve güvenlik kontrolünden sonra ancak G / Ç'den önce değiştirirse ne olur? Senaryo tür Java neden Stringişaretlenir final(benzer sealed) olduğuna inanıyorum ve aynı mantık bazı C # kararları dayanır bahis.
Darien

4

Bir sınıf mühürlendiğinde, tam olarak neyle uğraştıklarını bilmek için bu türü kullanan kodlara izin verir.

Şimdi C # ' stringda sealed, ondan miras alamazsınız, ancak bir saniye için durumun böyle olmadığını varsayalım. Eğer yaptıysanız, birisi böyle bir sınıf yazabilir:

public class EvilString// : String
{
    public override string ToString()
    {
        throw new Exception("I'm mean");
    }
    public override bool Equals(object obj)
    {
        return false;
    }
    public override int GetHashCode()
    {
        return 0;
    }
}

Bu şimdi tasarımcıların doğru stringolduğunu bildikleri her türlü özelliği ihlal eden bir dize sınıfı olacaktır. EqualsYöntemin geçişli olacağını biliyorlardı , bu değil. Heck, bu eşittir yöntemi, simetrik bile değildir, çünkü bir dize ona eşit olabilir, ancak o dizeye eşit olmaz. Eminim ToStringyöntem stringnull olmayan değerler için bir istisna atmayacak varsayımı altında kod yazmış her türlü programcı vardır . Artık bu varsayımı ihlal edebileceksiniz.

Bunu yapabileceğimiz başka sınıflar ve ihlal edebileceğimiz diğer varsayımlar da var. İçin dil özelliğini kaldırırsanızsealeddil tasarımcıları artık tüm kütüphane kodlarında bu gibi şeyleri hesaba katmaya başlamalıdır. Kullanmak istedikleri türlerin genişletilmiş türlerinin "düzgün" olarak yazıldığından emin olmak için her türlü kontrolü gerçekleştirmeleri gerekir, bu da yapılması çok pahalı bir şey olabilir (hem geliştirme zamanında hem de çalışma zamanında). Bir sınıfı kapatarak bunun mümkün olmadığından ve kendi türlerinin uygulama ayrıntıları hakkında yaptıkları iddiaların, kasıtlı olarak genişletilmek üzere tasarlanan türler dışında ihlal edilemeyeceğinden emin olabilirler. Genişletilmek üzere tasarlanan bu türler için, dil kodunun onlarla nasıl başa çıktığı konusunda çok daha savunmacı olması gerektiğini göreceksiniz.


Ancak kodunuzdaki bu varsayımı ihlal edebilirsiniz . Bu, String'in kaynağını alıp düzenlemek gibi değil. Tasarımcılar bunu hesaba katmak zorunda kalmayacaktı çünkü 1 yaprak, 1 şube, 1 müşteri kendi riski ve takdirine bağlı olarak kullanıyor. Diğer müşteriler bunu yapmayı tercih etmedikçe, oradan yayılmaz. Ve bunun gibi.
cregox

3
@Cawas Ve bir istisna beklenmedik bir zamanda atılırsa ve sonuç olarak bir kaynak sızdırılırsa veya bir sınıf belirsiz bir durumda bırakılırsa ve uygun olmayan şekilde çalışırsa? Bu durum biraz aptalca, ama birisinin mantıklı olduğunu düşündüğü bir uygulama yazması kolay olabilir, ancak zaman zaman belirli değerlerle çalışmadığında veya çalışmadığında atar. Daha sonra dil kodu çalışmadığında şikayet edecekler. İnsanların dilin destekleyemeyeceği şeyler yapmalarına izin vermemek tercih edilir.
Servy

Her durumda bir derleyici oluşturmaktan bahsediyorsunuz. sealedKullanıma açık olmayan yerleşik birçok özellik var. Hala neden bu kadar dar bir kapsamın dışında kullanıldığını açıklamıyor ve derleyici kodu kadar dar olması bile sealedvarlığını açıklamıyor .
cregox

2
@Cawas stringTür derleyici kodu değil. Dil kodunun bir parçası. Tamamen farklı. Her durumda, sadece bir örnek seçtim. BCL'nin tamamındaki herhangi bir mühürlü sınıfı alabilir ve bunu örnek olarak kullanabilirsiniz.
Servy

4
@Cawas: Bence burada eksik olan şey müşteri destek yönü. Bir sınıfın kalıtsal olmasına izin verirseniz, müşteriler sınıftan miras alacaktır ve kırıldığında sizi arayacaklardır. Tüm gün boyunca bu sınıftan kendi riskleri altında miras aldıklarını söyleyebilirsiniz , ancak yine de çağrıyı alacaksınız, çünkü ondan miras almalarına izin verdiniz , bu yüzden bunu yapmanın güvenli olduğunu varsayıyorlar.
Robert Harvey

3

Mühürlü kullanmak için iyi bir neden var mı?

Enh? Sık değil. Ben iletmenin türüyle (veya başka bir sınırlama) olduğunda sadece mühürlü kullanılan olacaktır gerçekten gerçekten değişmez kalması gerekiyor ve ben güven varisleri sisteme ince, felaketli hata tanıtan olmadan bu şartı furfill için olamaz.

Mühürlü kullanmak için iyi bir neden olduğunu varsayalım ve her şey için varsayılan olarak kullanmalıyız, miras ile ne yapıyoruz?

Varsayılan olmayan şeyler için kalıtım kullanırız. Kompozisyon kalıtsallıktan yana olsa bile (ve öyle), bu kalıtımın atılması gerektiği anlamına gelmez. Bu, kalıtımın, tasarım ve kod sürdürülebilirliği ile ortaya koyduğu bazı temel problemlere sahip olduğu anlamına gelir ve kompozisyon (genel olarak) daha az problemle aynı şeyi yapar. Ve bu, kompozisyon tercih edilmesine rağmen, kalıtımın belirli problem alt kümeleri için iyi olduğu anlamına gelir.

Ben olmak istemem çok ortalama ama sadece şimdi KATI ve birim test duydum eğer, belki de rock ve aslında yazma kodu underneith kurtulmak gerekir. İşler net bir şekilde kesilmez ve nadiren "her zaman X yapar" veya "asla Y kullanmayın" ya da "Z en iyisidir" doğru yol olacaktır (sanki sorunuzun görüşlerine göre yönelirsiniz gibi). Kod yazarken, diğer herhangi bir ödünleşimde olduğu gibi,sealed iyi olabilecek vakaları ve kedere neden olduğu vakaları görebilirsiniz .


Bana göre, bu ve "istemcilere kalıtımı desteklemekten kaçınmak", Robert'ın detaylandırmak istemediği en umut verici cevaplar ... Belki de kullandığınız davalarda daha fazla ayrıntı verebilir misiniz sealed?
cregox

@Cawas - İyi yapabileceğimden emin değilim. Çok nadiren yaparım ve genellikle bir şeyin değişmez kalmasının garantisinin (performans optimizasyonları yapmak, tasarım basitleştirmek için) nesneden miras kalmaya değmediği bir ödünleşmedir.
Telastyn

Çok havalı. Dunk zaten dunk etti! : P Cevap için çok teşekkürler. Uzmanlığım hakkındaki "ince ipuçlarını" toplayan tek kişi sensin. Sanki insanlar daha fazla bildiğimi sanıyorlardı, bilmiyorum ... Ama keşke "sadece kodlama" beni bu kayadan çıkarır. Belki de bu kavramları, muhtemelen yapmam gerektiği kadar prosedürel olarak değil, bir şekilde uyguluyorum.
cregox

3

Her şeyden önce, Eric Lippert'in Microsoft'un neden sınıflarını mühürlediğine dair yazısını okumalısınız.

http://blogs.msdn.com/b/ericlippert/archive/2004/01/22/61803.aspx

İkinci olarak, kapalı anahtar kelime tam olarak ne yaptığını yapmak için var - kalıtımı önlemek. Devralmayı önlemek istediğiniz birçok durum vardır. Koleksiyonunuz olan bir sınıfı düşünün. Kodunuz belirli bir tarzda çalışan bu sınıfa bağlıysa, o sınıftaki yöntemlerden veya özelliklerden birini geçersiz kılan ve uygulamanızın başarısız olmasına neden olan birisinin olmasını istemezsiniz.

Üçüncüsü, mühürlü kullanılması, kalıtım üzerine kompozisyonu teşvik eder, bu da içine girmek için iyi bir alışkanlıktır. Kompozisyonun miras üzerinde kullanılması, Liskov'un ikame ilkesini kıramayacağınız ve Açık / Kapalı prensibini izlediğiniz anlamına gelir. sealedbu nedenle oo programlamanın en önemli beş ilkesinden ikisinde size yardımcı olan bir anahtar kelimedir. Bunun çok değerli bir özellik olduğunu söyleyebilirim.


İlk kısım soru yorumlarında zaten belirtilmiştir. İkinci bölüm, gerçek sebepler olmadan sadece daha fazla muhakeme. Üçüncü bölüm, başka bir yere yaklaşmış olsa bile, bir şeyleri olabilir. Ben buna odaklanacağım.
cregox

üçüncü nokta, miras üzerine kompozisyonu teşvik etmez, en iyi genel seçim olsa bile mirası bir seçenek olarak tamamen ortadan kaldırır.
Michael Shaw

Bu, kod tabanını kontrol edip etmemenize bağlıdır. Sınıfları mühürlerseniz, gerekirse daha sonra istediğiniz zaman tekrar açabilirsiniz.
Stephen

2

Bu sorunun objektif bir cevabı olmadığını ve her şeyin sizin bakış açınıza bağlı olduğunu düşünüyorum.

Bir taraf, bazı insanlar her şeyin "açık" olmasını ister ve her şeyin doğru şekilde çalışmasını sağlama yükü, sınıfı genişleten kişidir. Bu yüzden sınıflar varsayılan olarak mirasa açıktır. Java yöntemlerinin neden varsayılan olarak sanal olduğunu.

Diğer tarafta, bazıları her şeyin varsayılan olarak kapatılmasını ve açmak için seçenekler sunmasını ister. Bu durumda, "açık" hale getirdiği her şeyin akla gelebilecek herhangi bir şekilde güvenli olduğundan emin olması gereken temel sınıfın yazarıdır. Bu nedenle C # 'da tüm yöntemler varsayılan olarak sanal değildir ve geçersiz kılmak için sanal olarak bildirilmesi gerekir. Aynı zamanda "açık" varsayılanları atlatmanın bir yolu olması gereken insanlar içindir. Sınıfı kapalı / final yapmak gibi, çünkü sınıftan türeyen birini kendi sınıfının tasarımında büyük bir sorun olarak görürler.


Bu daha çok benziyor! Bu iyi bir sebep olabilir ... "Çünkü insanlar kapatmak istiyor". Ve aynı zamanda soruda söylemeye çalışıyorum: C ++ sanal olmayan sınıflar geçersiz kılınabilir gibi görünüyor. sealedolamaz. Onlardan nasıl miras alabiliriz? Tüm okuduğum şey yapamayız. Hiç. Bilmiyorum. İlk defa mühürlü olduğunu duyduğumdan beri bu konuda 4 aydır devam ediyorum. Ve mühürlü bir sınıfta herhangi bir şeyi değiştirmem gerektiğinde bunu nasıl doğru yapacağımı hala bilmiyorum . Yani, "açma seçeneği" görmüyorum!
cregox

4
Bu nedenle C ++ sınıf yöntemleri varsayılan olarak sanal değildir. Bir yöntemi sanal yapmak, yöntem arama tablosunda ek ek yük olması gerektiği anlamına gelir ve C ++, özelliği istediğinizde yalnızca ek yük için ödeyeceğiniz felsefesine sahiptir.
Michael Shaw

@Ptolemy Tamam, kaldırdım. Hiç yazmamalıydım, çünkü insanların şikayet etmeye başladığını biliyordum.
Euphoric

Hey, insanların varsayılan olarak kapalı sınıflar yazmak istediğini ve aktif olarak açmayı seçmeleri gerektiğini iddia etmek istiyorsanız, o zaman payetlerde debriyaj yapmak zorunda kalacaksınız
Michael Shaw

IMO, API'lar söz konusu olduğunda özel / korunan / genel tartışmalara son derece benzemektedir: Sınıfı kimin kontrol edeceğine, sınıfı kimin devralmak istediğine, ikisi arasındaki iletişime ve yeni sürümlerin ne sıklıkla ortaya çıktığına bağlıdır.
Darien

-2

C # ile mühürlü sorun oldukça son olmasıdır. C # ticari geliştirme 7 yıl içinde, onu gördüğüm tek yer, ayarlanmış davranışı uygulamak için bir çerçeve sınıfı genişletmek için meşru bir neden olduğunu hissediyorum Microsoft .NET sınıflarında olduğunu ve sınıf mühürlendi, çünkü yapamadım .

Kullanılabilecek her türlü yolu düşünen ve hiçbirinin meşru olmadığına karar veren bir sınıf yazmak imkansızdır. Benzer şekilde, çerçeve güvenliği miras alınmayan sınıfa bağlıysa, bir güvenlik tasarım kusurunuz vardır.

Sonuç olarak, mühürlenmiş olanın yararlı bir amaca hizmet etmediği fikrine kesinlikle inanıyorum ve şimdiye kadar burada okuduğum hiçbir şey bu görüşü değiştirmedi.

Şimdiye kadar mühürlü haklı gösteren üç argüman olduğunu görebiliyorum.

  1. Tartışma 1, insanlar sınıflardan miras aldıklarında ve daha sonra içselleri gerçekten anlamadan o sınıfın içlerine daha fazla erişime sahip olduklarında bir hata kaynağını ortadan kaldırmasıdır.

  2. Argüman 2, bir microsoft sınıfını genişletir ve ardından microsoft bu sınıfta bir hata düzeltmesi uygular, ancak uzantınız bu hataya dayanırsa, kodunuz şimdi bozulur, microsoft suçu alır ve mühürlü

  3. Tartışma 3, sınıfın geliştiricisi olarak, sınıf tasarımımın bir parçası olarak, onu genişletmenize izin verip vermememdir.

Bağımsız değişken 1, son programcı kodumu nasıl kullanacağınızı bilmediğinizin bir argümanı gibi görünüyor. Durum bu olabilir, ancak yine de nesneler arayüzüne erişmeme izin verirseniz, nesnenizi kullandığım ve nasıl kullanılacağını anlamadan ona çağrı yaptığım doğru olur ve bu şekilde bu kadar zarar verebilir. . Bu mühürlü ihtiyacın zayıf bir gerekçesi.

Arg 2 için olgusal tabanın nereden geldiğini anlıyorum. Özellikle microsoft, Windows XP'nin Windows NT ile karşılaştırıldığında genel kararlılığını geliştiren, ancak Windows XP piyasaya sürüldüğünde birçok uygulamanın kırıldığı kısa vadeli maliyetle, hatalı biçimlendirilmiş çağrıları tanımlamak için win32 api çağrılarına ek OS kontrolleri yaptığında. Microsoft, bu denetimlerin söylenmesi için 'kurallar' koyarak bunu çözdü, uygulama X bu kuralı ihlal ettiğinde yoksay, bilinen bir hata

Argüman 2 kötü bir argüman çünkü en iyi mühürlü bunun yanında bir fark yaratmıyor çünkü .NET kütüphanesinde bir hata varsa, bir iş bulmaktan başka seçeneğiniz yok ve microsoft fix ortaya çıktığında, büyük olasılıkla demek ki, etrafınızdaki kırık davranışa bağlı olan işiniz artık bozuldu İster miras kullanarak ister başka bir ek sarmalayıcı kodu kullanarak bu sorunu çözmüş olsanız da, kod sabitlendiğinde, etrafınızdaki çalışma bozulacaktır.

Argüman 3, kendisini haklı çıkaracak herhangi bir maddeye sahip olan tek argüman. Ama yine de zayıf. Sadece kod yeniden kullanımına karşı gider.


2
/ me microsoft'a bir e-posta gönderir, lütfen benim için X sınıfını açıp yeni bir .NET sürümü gönderebilirsiniz. Saygılarımla, .... Dediğim gibi, ticari gelişimde sadece kapalı bir sınıf gördüm, onu açığa çıkarmak mümkün değildi.
Michael Shaw

6
It is impossible to write a class thinking about every possible way it could be used- Pek çok Framework sınıfının mühürlenmesinin nedeni budur ... Birinin sınıfı genişletebileceği her türlü yolu düşünme ihtiyacını ortadan kaldırır.
Robert Harvey

5
Sızdırmaz olsaydınız, mühürlemenin pek bir anlamı olmazdı, değil mi?
Robert Harvey

2
@Ptolemy İnsanların sınıfınızı genişletmesine izin vermek bir özelliktir . Önemli miktarda geliştirme çabası tüketen. Bu, sadece sınıfın yazarının, çabayı haklı çıkarmak için potansiyel uzantılarda yeterli fayda görüp görmediğini haklı çıkarmaya değer bir özelliktir. Çabaları haklı gösteremezlerse ve bu nedenle tür ve kullanıcıları, uzantıyı destekleyecek şekilde tasarlanmamışsa, bunu önlemek önemlidir, aksi takdirde türü genişletebilirsiniz, ancak aşağıdaki durumlarda düzgün çalışma olasılığı düşüktür. bunu yaparsınız.
Servy

2
@Cawas: Sadece zor oluyorsun.
Robert Harvey


-8

Sorumdan da anlaşılacağı gibi, burada uzman değilim. Ama var olmak için hiçbir neden göremiyorum sealed.

Kod mimarlarının bir arayüz tasarlamasına yardımcı olmak için yapılmış gibi görünüyor. Vahşi doğada çıkacak bir sınıf yazmak istiyorsanız ve birçok insan ondan miras alacaksa, o sınıftaki herhangi bir şeyi değiştirmek onu çok fazla insan için kırabilir. Böylece onu mühürleyebiliriz ve kimse miras alamaz. "Sorun çözüldü".

Şey, "bir noktayı örtmek ve bir başkasını ortaya çıkarmak" gibi görünüyor. Ve bir problemi bile çözmüyor - sadece bir aracı yok ediyor : kalıtım. Herhangi bir araç olarak, birçok kullanımı vardır ve dengesiz bir sınıftan miras almak, aldığınız bir risktir. Bu riski alan herkes daha iyi bilmelidir.

Belki bir anahtar kelime olabilir stable, bu yüzden insanlar anahtar kelimeyi devralmanın daha güvenli olduğunu bilir.


2
"Sorun çözüldü" - Kesinlikle.
Robert Harvey

@RobertHarvey Bir sonraki paragrafta açıklandığı gibi çözülmedi.
cregox

8
Sadece delisin çünkü sınıfı genişletemezsin. Bu sealed, çerçeve tasarımcıları için yararlı bir araç olmadığı anlamına gelmez . Bir çerçevedeki sınıflar kara kutular olmalıdır; düzgün kullanabilmek için bir sınıfın içini bilmeniz gerekmez. Yine de miras budur.
Robert Harvey

Hiç faydalı olmadığını söylemedim. Ben onun kullanımını görmediğimi söylüyorum ve nedenini belirtiyorum. Lütfen, sana yalvarıyorum, kullanmak için bana iyi bir sebep ver! Sadece "çünkü kapalı bir tasarım modelini takip etmek istiyorum" olsa bile, sorun değil. Açıkçası bu sebebi veren kimseyi görmüyorum.
cregox

7
Bunun iyi bir nedeni, mühürlü bir sınıfta kalıtımı desteklemek zorunda olmamanızdır.
Robert Harvey
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.