Özel değişkenlere neden ihtiyacımız var?


210

Sınıflarda neden özel değişkenlere ihtiyacımız var?

Okuduğum her programlama kitabı bunun özel bir değişken olduğunu söylüyor, onu nasıl tanımladığınızı ancak orada durduğunu söylüyor.

Bu açıklamaların ifadesi, her zaman bana, mesleğimize olan güven krizimiz gibi geldi. Açıklamalar her zaman diğer programcıların kodumuzu bozmak üzere olduğu gibi geliyordu. Ancak, özel değişkenleri olmayan birçok programlama dili vardır.

  1. Özel değişkenler neleri önlemeye yardımcı olur?

  2. Belirli bir mülkün özel olup olmamasına nasıl karar verirsiniz? Eğer varsayılan olarak her alan özel olmalı, o zaman neden bir sınıfta genel veri üyeleri var?

  3. Bir değişken hangi koşullar altında halka açıklanmalıdır?


9
Sorunuz çok dille agnostik geliyor, ancak onu java ve c ++ olarak etiketlediniz. Bu iki dilin dışından bakış açılarıyla ilgileniyorsanız, muhtemelen söylemelisiniz.
James,

8
Kayıt için, özel bir yöntem oluşturmak "güvenliği" arttırmaz. Uygulamanızın diğer bölümleri yansıma kullanarak yine de özel üyelere erişebilir.
kba

3
Özel ve kamusal değişkenlerin kullanımı ve farklılıkları ve neden bunlara sahip olduğumuz, yalnızca genel Nesneye yönelik ilkeler bağlamında anlaşılabilir. Ayrı ayrı anlaşılamaz. Muhtemelen bu perspektiften bakmanız gerekir, işler daha açık olabilir.
Nazar Merza,


3
Otomobilinde emniyet kemeri kullanan birini yakalarsanız, ehliyetlerini elinizden almalısınız, çünkü araç kullanmada kendi yeteneklerine güvenmedikleri açık.
gnasher729

Yanıtlar:


307

Bu çok fazla bir güven meselesi değil, karmaşıklığı yöneten biri.

Sınıfın dışından bir kamu üyesine erişilebilir, pratik düşünceler için "potansiyel olarak her yerde" anlamına gelir. Genel bir alanda bir şeyler ters giderse, suçlu herhangi bir yerde olabilir ve böylelikle hatayı bulmak için oldukça fazla koda bakmak zorunda kalabilirsiniz.

Buna karşılık özel bir üyeye yalnızca aynı sınıfın içinden erişilebilir, bu nedenle bir şey yanlış giderse, genellikle yalnızca bir kaynak dosya bulunur. Projenizde milyonlarca kod satırı varsa, ancak sınıflarınız küçük tutulursa, bu hata izleme çabalarınızı 1000 kat azaltabilir.

Diğer bir avantaj, 'eşleştirme' kavramı ile ilgilidir. Bir kamu üyesi mbir sınıfın Abaşka bir sınıf tarafından kullanılan Bbir bağımlılık tanıtır: Eğer değiştirirseniz miçinde A, ayrıca kullanımlarını kontrol etmek zorunda miçinde B. Daha da kötüsü, sınıftaki hiçbir şey Anerede mkullanıldığını size söylemez , bu yüzden yine tüm kod tabanında arama yapmanız gerekir; eğer yazdığın bir kütüphane ise, dışardaki koddan da emin olman gerekir.Projeniz, yaptığınız değişiklik nedeniyle bozulmuyor. Uygulamada, kütüphaneler ne kadar acı verici olursa olsun, orijinal yöntem imzalarına mümkün olduğunca bağlı kalma eğilimindedir ve daha sonra büyük bir sürüm güncellemesi ile değişiklik kırma bloğu ortaya çıkarır. Özel üyelerle, aksine, bağımlılıkları hemen dışlayabilirsiniz - dışardan erişilemezler, böylece tüm bağımlılıklar sınıf içinde yer alır.

Bu bağlamda, "diğer programcılar" geleceğinizi ve geçmişinizi içerir. Şansı biliyor vardır şimdi size değişken Y ile bu şey X yapmamam gerektiğini, ancak üç ay müşteri acilen bazı özelliği uygulamak sana ihtiyacı yolda unutmuş bağlı konum ve X sonları yapıyor neden acaba Belirsiz şekillerde Y.

Bu yüzden, ne zaman özel şeyler yapmanız gerektiğine gelince: Her şeyi varsayılan olarak özel yapalım ve sonra sadece kesinlikle halka açık olan kısımları gösterin. Ne kadar çok özel yapabilirseniz o kadar iyi.


24
Sorunun merkezine gelmek için +1 olsa da, sık sık kullanılan bir değişkenin özel kalmasını sağlamak için kasnaklardan geçmeyi bıraktığımda kodumu korumayı daha kolay buldum. Gelecekte bir hatanın ortaya çıkabileceğinden emin olabilirsiniz, ancak gözden geçirilmesi gereken 60 kod satırı daha az, önyüklemek için daha az değişken ve fonksiyon var;)
Jeffrey Sweeney

48
Modern hesaplamanın kutsal kâsesi karmaşıklığı azaltıyor.

1
Hata ayıklamanın bir kısmının sadece “neyin yanlış gittiğini” doğrudan doğruya sürmekle kalmayıp, “neyin yanlış gitmediğini” anlamaya doygunluk sürecini almak ve kalanı araştırmaya odaklanmak olduğunu her zaman söylemeyi seviyorum. Derleyicinin bana, "neyin olamayacağını" tanımlaması için özel değişkenler gibi araçlarla yardım etmesini sağlayabilirsem, bu bana zaman kazandırıyor. Sadece neyin yanlış gittiğini ispatlayamadığım nadir durumlarda, belki de özel verilerimin üzerine yazılan bir arabellek taşması gibi daha korkutucu varsayımlara bakmam gerekir.
Cort Ammon

2
Tam olarak. İnsanlar "bilgi saklanarak" duymak, onlar şifreleme anahtarları, veritabanı kimlik bilgileri vs. gibi şeyler için özel değişkenler kullanması gerektiğini düşünüyorum
Wayne Werner

2
@AdamZerner, alıcıların / ayarlayıcıların ilk sırada yer almasını " söyleme , sorma" ( martinfowler.com/bliki/TellDontAsk.html ) konusuna bakın - her zaman değerin iç gösterimini istediğiniz zaman değiştirmelisiniz dilersin. Her zaman olduğu gibi, istisnalar var ... (örneğin
DTO'lar

111

Özel değişkenler, kodunuzun belirli bölümlerine bağlı olarak insanların önlenmesine yardımcı olur. Örneğin, bazı veri yapılarını uygulamak istediğinizi varsayalım. Veri yapınızdaki kullanıcıların onu nasıl uyguladığınıza aldırış etmelerini istemezsiniz, yalnızca uygulamayı iyi tanımlanmış arayüzünüzle kullanın. Bunun nedeni, hiç kimse uygulamanıza bağlı değilse, istediğiniz zaman değiştirebilmenizdir. Örneğin, performansı artırmak için arka uç uygulamasını değiştirebilirsiniz. Arayüz kullanıcıları iyi olurken, uygulamalarınıza bağlı olan diğer geliştiriciler bozulur. Sınıf kullanıcılarını etkilemeden uygulamaları değiştirme esnekliğine sahip olmak, özel değişkenleri (ve daha genel olarak kapsülleme ) kullanmanın size sağladığı büyük bir avantajdır .

Ayrıca, gerçekten bir "güven krizi" değil. Eğer bir veri parçasını halka açıklarsanız, kimsenin buna bağlı olmadığından emin olamazsınız. Genel ara yüze geçmek yerine, özellikle bir son teslim tarihinin sıcağında, uygulamaya özel bazı değişkenlere güvenmek genellikle çok uygundur. Dahası, geliştiriciler her zaman değişebilecek bir şeye bağlı olduklarını farketmeyeceklerdir.

Yani bu tür sorularınızı cevaplıyor, umarım. Tüm uygulama detaylarınız özel olmalı ve genel kısım, sınıfınızı kullanmak için küçük, özlü ve iyi tanımlanmış bir arayüz olmalıdır.


24
IMO aynı zamanda lib yazar ve lib tüketici arasındaki iletişim ile de ilgilidir. Kamu arayüz "Bunu kullanmak" gibi ve erler gibi olması dışında Java, siz "o kullanmayın" Gerçekten o özel bu şekilde daha güvenli ve çok daha net böylece yaparsanız kazara kullanamazsınız.
chakrit

5
@chakrit ve diğerleri: Özel alanlarınızı ve yöntemlerinizi kullanmak için gerçekten dışarıda olanlar bunu yapabilir (yansıtma yoluyla). private"öncelikle güvenlik için tasarlanmadı" dan daha az olduğundan, konuşulacak bir "güvenlik" sağlamaz. Erişmek için değil (derleyici aracılığıyla verilen) güçlü bir ipucu.

@delnan "tesadüfen" cümlesine evet, belki de bu konuda daha net olmalıyım.
chakrit

@chakrit Evet, yanıldığınızı ima etmek istemedim. Sadece bu noktayı tanıtmak istedim.

1
@delnan: Özel alanlar bazı dillerde belirli güvenlik biçimleri sağlıyor. Örneğin, Eric Lippert’in cevabına bakınız . Erişim seviyeleri ve değiştiricileri (özel, mühürlü vb.) C # 'da güvenlik amaçlı mıdır? .
Brian,

25

Buradaki anahtar kelime, Encapsulation . OOP'de nesnelerinizin / sınıflarınızın uygun şekilde kapsüllenmesini sağlamak için özel değişkenleri kullanmak istiyorsunuz.

Diğer programcılar sizi almak için dışarıdayken, kodunuzla etkileşime girerler. Eğer bir değişkeni özel yapmazsanız, zarar vermek istemeden kendi kodlarında belirtebilirler. Ancak, sınıfınıza geri dönüp bir şeyi değiştirmeniz gerekirse, kimin hangi değişkeni ve nerede kullandığını artık bilemezsiniz. Kapsüllemenin amacı, sınıfın dış arabirimini açık yapmaktır, böylece yalnızca bu (tipik olarak) yöntemlerin başkaları tarafından kullanılabileceğini bilirsiniz.

  1. Bu nedenle, özel değişkenler karşılık gelen değişkenin yalnızca tanımlayıcı sınıfta kalmasını sağlar. Değiştirmeniz gerekirse, değişiklik sınıfın kendisinde yereldir.

  2. C ++ veya Java gibi geleneksel dillerinde, her şeyi özel ve yalnızca ilgili alıcılar ve ayarlayıcılar tarafından erişilebilir hale getirirsiniz. Gerçekten karar vermene gerek yok.

  3. Bazen, f.ex. Bir C ++ yapısında, sadece birkaç şeyi birlikte gruplamanın bir yolu olarak bir sınıfa ihtiyacınız vardır. Örneğin, yalnızca xve yniteliği olan bir Vector sınıfını göz önünde bulundurun . Bu durumlarda, herkese açık olarak ilan ederek bu özelliklere doğrudan erişime izin verebilirsiniz. Özellikle, dışarıdaki bazı kodların doğrudan xveya içine yeni değerler yazarak sınıfınızın bir nesnesini değiştirip değiştirmemesine dikkat etmemelisiniz y.

Ek bir nokta olarak, bu konunun diğer dillerde biraz farklı olduğuna dikkat edin. Örneğin, işlevsel programlamaya güçlü bir şekilde dayanan diller veri değişkenliğini vurgular, yani veri değerleri hiçbir şekilde değiştirilemez. Bu gibi durumlarda, diğer programcıların (veya onların kodlarının) verilerinize ne yaptığına dikkat etmeniz gerekmez. Kodunuzu etkileyebilecek hiçbir şey yapamazlar, çünkü tüm veriler değişmezdir.

Bu nedenle, bu nedenle , bir alıcılar ve ayarlayıcılar gibi yöntemleri kasten ayırt etmeyen, ancak değişkene / işleve doğrudan erişim sağlayan, tek biçimli erişim ilkesi adı verilen bir şey alırsınız . Dolayısıyla, özel beyannamelerin nesne yönelimli senaryolarda çok daha popüler olduğunu söyleyebilirsiniz.

Bu aynı zamanda, bilginizi başka alanlara dahil etmek için genişletmenin, mevcut kavramları yepyeni bir şekilde nasıl görmenizi sağladığını gösterir.


1
+1 "Diğer programcılar sizi almak için dışarıdayken, kodunuzla etkileşime giriyorlar." Kodunuzu kullanan programcılar doğal olarak kötü değildir. Özel değişkenleri kullanarak, kodların (ve gelecekteki) size zarar vermediğinden emin olursunuz. Ayrıca daha iyi bir API tasarlamanıza ve belgelemenize yardımcı olur.
szalski

7

Özel değişkenler, daha sonra bir nesne veya işlev kapsamı dışındaki referansların yanlışlıkla diğer değişkenleri etkilememesini sağlar. Büyük programlama projeleri için bu, pek çok ilginç sorunun (genellikle derleyici tarafından yakalanmayan) kaçınmasına yardımcı olabilir.

Örneğin, Javascript gibi prototip dilleri, kullanıcıların uygun gördükleri değişkenleri sıvalarına izin verebilir:

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

Bu değişken özel olsaydı, dışarıdan değiştirilemezdi:

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

Bununla birlikte, tüm değişkenlerin özel olması gerekmez ve özel değişkenlerin aşırı kullanımı, kodu daha hantal hale getirebilir. Bir nesneyi ciddi şekilde etkilemeyen önemsiz alanlara ihtiyaç duyulmaz get()ve set()yöntemler.

Özel değişkenler, gelecekte pek çok genel değişkenin ne olduğuna ilişkin ağır belgelere güvenmeksizin, kodu genişletmeyi de kolaylaştırır. Daha az değişkenin üzerine yazılabiliyorsa, yanlışlıkla işlevsellik kırma tehdidinde daha az tehlike vardır.

Genel değişkenler, bir nesne / işlev diğer nesnelere / işlevlere erişirken kullanılacaktır, çünkü kural olarak özel değişkenler bunu yapamaz. Birkaç ila birkaç ortak değişken arasında herhangi bir yere sahip olabilirsiniz ve doğru kullanılırsa bunları kullanmak kötü bir şey değildir.


3'ü uyarmanın neden "ah ah!" Olduğu belli değil. bu durumda. Belki de programcının olmasını istediği şey buydu.
immibis

@ immibis Belki, ve belki de cevapta daha fazla ayrıntı vermeliydim. Ancak, mülklere erişim, potansiyel olarak uygulama ayrıntılarını ifşa ettiğiniz için açık-kapalı ilkesi veya LoD gibi bazı OOP ilkelerini ihlal etmek için kapıyı açabilir. Tabii ki amacınıza göre mülkün tam olarak ne olduğuna bağlı. Çoğu dil, nesneleri referans olarak kullanır ve nesnelerin referansları etrafından dolaştığında ve diğer aygıtlar sessizce özelliklerini değiştirdiğinde, hata ayıklamak gerçekten zor olabilir. IMO, bir sınıf örneğiniz varsa, yöntemlerle çalışmak çok daha kolay ve daha genişletilebilir.
Jeffrey Sweeney

7

Gelecekteki bakıcılara ve bir sınıfın kullanıcılarına faydalarını gösteren iyi cevaplar vardır. Ancak, özgün tasarımın da faydaları vardır. Amacınız ne zaman kendiniz için işleri kolaylaştıracağınız ve hedefiniz sınıf kullanıcısı için işleri daha kolay hale getirme arasında net bir ayrım noktası sağlar. Genel ve özel arasında seçim yaptığınızda, bir mod veya diğerine geçmek beyninize işaret eder ve daha iyi bir API ile bitirdiniz.

Gizliliği olmayan dillerin böyle bir tasarımı imkansız hale getirmediği, sadece daha az muhtemel olduğu değildir. Gibi bir şey yazmaları istendiğinde foo.getBar(), insanlar bir alıcının gerekli olmadığını düşünmeye meyillidirler, çünkü yazmak daha kolaydır foo.bar, ancak daha sonra gibi uzun canavarlarla sona erdiğinde bu karar tekrar gözden geçirilmez obj.container[baz].foo.bar. Daha katı bir dilde hiç çalışmamış olan programcılar, bunun neyin yanlış olduğunu görmeyebilir.

Bu nedenle, gizlilik içermeyen dillerde, tüm "özel" üyelere bir alt çizgi hazırlama gibi, onu simüle eden adlandırma standartlarını sık sık benimsemelerin nedeni budur. Dil onu zorlamadığında bile yararlı bir sinyaldir.


3

Tüm değişkenler kesinlikle herkese açık olmadıkça özel olmalıdır (bu neredeyse hiçbir zaman, özellikleri / alıcıları ve ayarlayıcıları kullanmanız gerekir).

Değişkenler büyük ölçüde nesnenin durumunu sağlar ve özel değişkenler diğerlerinin girmesini ve nesnenin durumunu değiştirmesini önler.


5
Konuyla ilgili çok dar bir görünüm. Halka açık alana erişimin
güvence

Bir kimse, durumu değiştirilemeyen (değişmeyen nesneler) nesneler tasarlayabilir, ancak bu, tüm sınıflara uygulanan genel bir kural değildir. Tecrübelerime göre, çoğu nesne başkalarının nesnenin durumunu değiştirmesini çok kolaylaştırır.
David K,

1
@DavidK Belki de bbb'ın demek istediği şey, "özel değişkenler diğerlerinin girmesini engeller ve ayırt etmeden nesnenin durumunu değiştirmesidir." Genel yöntemler, nesnenin özel durumunu değiştirebilir, ancak yalnızca nesnenin işleyişi için gerekli ve tutarlı olan şekillerde değişebilir.
Max Nanasy

@Max Nanasy: Evet, herkes kamusal arayüzde sadece yöntemler önerdiğinde devletin nasıl değiştirileceğini kontrol edebilir . Örneğin, nesnenin "kendinden tutarlı" olması için tatmin edilmesi gereken üyeler arasında bir ilişki olabilir ve kendinden tutarlı bir durumun yalnızca başka bir kendinden tutarlı duruma değişmesine izin verebilirsiniz. Tüm bu değişkenler genelse, bunu zorlayamazsınız. Ancak , herhangi bir değişikliğe izin vermek istemediğiniz nesneler de olabilir , bu yüzden hangisinden bahsettiğimizi açıkça belirtmeniz önemlidir.
David K,

2
  • Özel değişkenler neleri önlemeye yardımcı olur?

Hangi özelliklerin ve yöntemlerin arayüz olduğunu ve hangilerinin gerçekte temel işlevsellik olduğunu netleştirmekle ilgilidir. Genel yöntemler / özellikler, diğer kodla ilgilidir, genellikle nesnelerinizi kullanan diğer geliştirici kodlarıdır. Aynı projede 100'den fazla takım üzerinde hiç çalışmamıştım, ancak yazdığım eşyaları kullanan 20'ye yakın geliştiriciden oluşan 3-5 kişilik ekipler deneyimimde diğer endişeler aptal görünüyor.

Not: Ben öncelikle bir JavaScript geliştiricisiyim. Kodumu inceleyen diğer geliştiriciler hakkında genellikle endişelenmiyorum ve eşyalarımı istediğim zaman yeniden tanımlayabilecekleri konusunda tam bir farkındalık içinde çalışıyorum. İlk ne yaptıklarını bilecek kadar yetenekli olduklarını varsayıyorum. Olmazsa, kaynak kontrolü kullanmayan bir ekip üzerinde çalışıyor olabilirim.

  • Belirli bir özellik kümesinin özel olup olmamasına nasıl karar veriyorsunuz? Eğer varsayılan olarak her alan özel olmalı, o zaman neden bir sınıfta genel veri üyeleri var?

Gerçekleştirilecek mülkün herhangi bir onayını veya diğer özel muamelesini yapmadığınız zaman özel mülklere alıcı ve alıcı koymanın aptalca olduğunu düşünürdüm. Hala her zaman gerekli olduğunu düşünmüyorum, ancak büyük ölçekli, yüksek karmaşıklık ile uğraşırken, ama en önemlisi, tutarlı bir şekilde davranan nesnelerinize dayanan birçok başka cihaz, işlerin bir arada yapılması yararlı olabilir. tutarlı ve düzgün bir yol. İnsanlar çağrılan yöntemleri gördüklerinde getThatvesetThat, niyetlerinin ne olduğunu tam olarak biliyorlar ve nesnelerinizi, domateslerden ziyade daima domates alabilecekleri beklentisiyle etkileşimde bulunmak için yazabiliyorlar. Olmazlarsa, nesnenizin muhtemelen yapmaması gereken bir şey verdiğini biliyorlar, bu başka bir nesnenin muhtemelen yapmaması gereken verilerle bir şeyler yapmasına izin veriyor demektir. İhtiyaç duyulduğunda kontrol edebilirsiniz.

Diğer büyük avantaj, nesnelerinizin bir tür değişen durum bağlamına dayalı olarak bir alıcı veya ayarlayıcıdan farklı şekilde değer vermesi veya yorumlanması daha kolay olmasıdır. Eşyalarınıza bir yöntemle eriştikleri için, nesneye bağlı olan diğer kodları kırmadan daha sonra çalışma şeklini değiştirmek çok daha kolaydır. Önemli olan, yalnızca nesnenizin aslında sorumlu tuttuğunuz verileri değiştirmesidir. Bu, kodunuzu gevşek bir şekilde bir arada tutmak için özellikle önemlidir; bu, taşınabilirlik ve değişiklik kolaylığı açısından büyük bir kazançtır.

  • Bir değişken hangi koşullar altında halka açıklanmalıdır?

Birinci sınıf işlevlerle (işlevleri argüman olarak iletebilirsiniz), daha küçük ölçekli projelerde bunu yapmak için fazlasıyla gerekli olmasının dışında pek çok harika neden düşünemiyorum. Onsuz, diğer nesneler tarafından yoğun ve düzenli bir şekilde işlenen üyelere sahip olduğunuzu varsayalım, sürekli olarak almanın ve bu verilere gerçekten dokunmayan bir nesnenin kümelerini çağırmanın biraz sakıncalı göründüğü kadarıyla. kendisi, nesnenin bu verilerden neden sorumlu olduğunu merak etmemi sağlayacaktı. Genel olarak konuşursak, kamuya açık bir veri özelliğinin gerekli olduğuna karar vermeden önce mimarlığımdaki kusurları tekrar incelemek istiyorum. IMO, genellikle kötü bir fikir olan bir şeyi yapmanıza izin veren bir dilde yanlış bir şey yoktur. Bazı diller aynı fikirde değil.


IMHO, tek amacı genel değişkenleri açığa çıkarmak olan bir kamu sınıfında özellikle yanlış bir şey yok . Nitekim, JVM bu amaçla yerleşik sınıfların bir numarası vardır: int[], double[], Object[], vb Bir gerektiğini, ancak, böyle bir sınıfın örneklerini ortaya nasıl hakkında çok dikkatli olun. void CopyLocationTo(Point p);[Arayandan bir kabul etmenin Point] anlamı, bundan daha açıktır Point location(), çünkü Point pt = foo.location(); pt.x ++;konumu üzerindeki etkisinin ne olacağı açık değildir foo.
supercat,

2

SO ile ilgili bir soru için bu yazıya bakınız .

Kısaca, değişken kapsam, tüketicilere kodunuzun ne olması gerektiğini ve neyle uğraşmaması gerektiğini göstermenizi sağlar. Özel bir değişken, tüm nesnenin tutarlı durumda olduğundan emin olmak için özellik ayarlayıcısı veya işleme yöntemi kullanılarak "onaylanmış" verileri tutabilir. Özel değişkenin değerini doğrudan değiştirmek, nesnenin tutarsız olmasına neden olabilir. Özel kılmak için, birisinin gerçekten çok çalışması ve değiştirmek için çalışma zamanı izinlerinin çok yüksek olması gerekir.

Doğru üye kapsamı bu nedenle kendi kendini belgeleyen kodda anahtardır.


2

Kapsüllemenin değeri hakkında gerçek bir örnek kullanarak farklı bir perspektiften konuşacağım. Bir süre önce (80'li yılların başında) Daggorath Zindanları adlı Radio Shack Color Computer için bir oyun yazıldı. Birkaç yıl önce, Richard Hunerlach bunu bir kağıt düzenleyiciden C / C ++ 'ya ( http://mspencer.net/daggorath/dodpcp.html ) yazdı . Bir süre sonra, kodu aldım ve daha iyi bir kapsülleme sağlamak için tekrar faktörlendirmeye başladım ( http://dbp-consulting.com/stuff/ ).

Kod, zamanlama, video, kullanıcı girişi, zindan yaratımı, canavarlar, vb. İşlemek için zaten farklı nesnelere çarpanlara ayrılmıştı, ancak kesinlikle meclisten taşındığını söyleyebilirdiniz. En büyük görevim kapsüllemeyi arttırmaktı. Bununla, burunlarını birbirlerinin işinden çıkarmak için kodun farklı bölümlerini almayı kastediyorum. Örneğin, video değişkenlerini doğrudan etkilenecek şekilde değiştirecek birçok yer vardı. Bazıları hata kontrolüyle yaptı, bazıları değil, bazılarının bu şeyi değiştirmenin ne olduğu hakkında biraz farklı fikirleri vardı. Kodun çoğaltılması vardı. Bunun yerine, video bölümünün istenen görevleri gerçekleştirmek için bir arayüze sahip olması gerekiyordu ve bunu yapmak için gereken kod tek bir yerde, bir fikirde, hata ayıklanacak bir yerde olabilirdi. Bu tür şeyler çok yaygındı.

Kod dağılmaya başladığında, teşhis edilmeyen böcekler ortadan kayboldu. Kod daha kaliteli hale geldi. Her görev, koddaki bir yerin sorumluluğudur ve onu düzeltmek için yalnızca bir yer vardı. (Koddan her yeni bir geçiş daha geçirdiğimde hala daha fazlasını buluyorum.

Kodunuzla ilgili görünen her şey sizin arayüzünüzdür. Öyle olsun ya da olmasın. Görünürlüğü mümkün olduğu kadar sınırlandırırsanız, daha sonra kodu yanlış yere koymanız istenmez. Hangi verilerin hangi koddan sorumlu olduğunu açıkça belirtir. Daha iyi, daha temiz, daha basit, daha zarif tasarım için yapar.

Bir nesneyi kendi verilerinden sorumlu yapar ve bir şeylerin olmasını isteyen herkese arayüzler sağlarsanız, kodunuz LOT'u daha basit hale getirir. Sadece düşüyor. Sadece bir şeyi yapan küçük ve basit rutinleriniz var. Daha az karmaşıklık == daha az hata.


"Lib kullanıcılarımızın özgürlüğü" ile "bizim için daha az sorun" arasındaki sıkı denge. Kapsüllemenin, kodlamada hataları önleyeceğim anlamında daha iyi olduğuna inanmaya başlıyorum ve son kullanıcıların da hataları önlemeye yardımcı olacağım. Fakat özgürlük eksikliği, basitçe onları da uzaklaştırabilir, alternatifler arayabilir ... Henüz kullanılmamış kodlama olabilir, ancak kamusal yöntemlerle öngörülen işlevsellikler bunu dengelemeye yardımcı olabilir, ancak daha fazla zaman gerektirir.
Kova Gücü


2

Güven veya saldırı korkusuyla hiçbir ilgisi yok, yalnızca Kapsülleme ile ilgili - sınıf kullanıcısı hakkında gereksiz bilgi zorlama değil.

Özel sabitleri göz önünde bulundurun - gizli değerler içermemelidir (bunlar başka bir yerde saklanmalı), değiştirilemezler, sınıfınıza geçmeleri gerekmez (aksi takdirde genel olması gerekir). Onlar için mümkün olan tek kullanım, DİĞER dersliklerinde sabitler. Ancak bunu yaparsanız, bu sınıflar artık sınıfınıza bağlıdır, sınıfınızla ilgisi olmayan işler yapmak için. Sabiti değiştirirseniz, diğer sınıflar kırılabilir. Bu, her iki taraftan da kötü - sınıfınızın yazarı olarak, olabildiğince değişme özgürlüğü istiyorsunuz ve kontrolünüz dışındaki şeyler hakkında endişelenmek istemiyorsunuz. Sınıfınızın bir tüketicisi, sınıfınızı değiştirmeden endişelenmeden ve kodlarını kırmadan endişelenmeksizin sınıfınızın açıktaki ayrıntılarına bağlı olmak istiyor.

Sınıfınızın bir tüketicisi, sınıfınızla ETKİLEŞMEK için gereken her şeyi bilmek ister ve sınıfınızla nasıl yaptıklarını değiştirmeyen hiçbir şey bilmek istemez: işe yaramaz bir durumdur. Eğer yansımalı bir dil kullandıysanız, bir sınıfın bir şeyi nasıl yaptığını ya da beklenmedik bir şekilde bir istisna attığını değil, sadece özel alanların ve metotların adını öğrenmek için ne sıklıkla kullandınız? Asla bahis yapmam. Çünkü bu bilgiyi kullanamazsın.


1

OOP kavramının mirası, özelliklerinden birine sahiptir (Java veya C ++). Yani miras alacaksak (miras alınan sınıfın değişkenlerine erişeceğimiz anlamına gelir), bu değişkenleri etkileme olasılığı vardır. Bu yüzden değişkenlerin değiştirilip değiştirilemeyeceğine karar vermeliyiz.

Sadece bu amaçla, OOP'de erişim değiştiricileri kullanıyoruz. Değiştiricilerden biri özeldir; bu, yalnızca o sınıfın erişebileceği anlamına gelir. Başka bir sınıf bu değişkenleri etkileyemez.

Bildiğimiz gibi, korunan, miras alacak olan sınıf tarafından erişilebilir olabileceği anlamına gelir.

Neden OOP’da bir değiştirici kavram var, bu nedenlerden kaynaklanıyor (herhangi bir sınıf OOP kavramını kullanarak diğer sınıf değişkenlerine erişebilir). Eğer değiştirici bir kavram yoksa, sınıfları miras alırken veya diğer OOP kavramlarını kullanırken bunun zor olacağı anlamına gelir.


1

Diğerleri tarafından belirtildiği gibi, özel değişkenler nesneyi tutarsız bir duruma götüren yanlış kullanımlardan kaçınmakta ve hataları ve öngörülemeyen istisnaları izlemekte güçlük çekmektedir.

Ancak öte yandan, diğerleri tarafından en çok göz ardı edilen şey korunan alanlarla ilgilidir.

Genişletilmiş bir alt sınıf, nesneyi bu tür alanların halka açık olduğu kadar kırılgan hale getirerek korunan alanlara tam erişime sahip olacaktır, ancak bu kırılganlık kendi kendini genişleten sınıfla sınırlıdır (bu alanları daha fazla göstermediği sürece).

Bu nedenle, genel alanların iyi olarak kabul edilmesi zordur ve bugüne kadar bunları kullanmanın tek nedeni yapılandırma parametresi olarak kullanılan sınıflar içindir (birçok alana sahip ve mantığı olmayan çok basit bir sınıf, böylece sınıf tek başına bir parametre olarak geçirilir). bazı yöntem).

Ancak diğer taraftan, özel alanlar, kodunuzun esnekliğini diğer kullanıcılara da düşürür.

Esneklik vs Sorunlar, artılar ve eksiler:

Vanilya sınıfındaki, korumalı alanlara sahip kodunuzla somutlaştırılan nesneler güvenlidir ve sizin sorumluluğunuzdadır.

Öte yandan, sınıfınızı, kod kullanıcıları tarafından başlatılan korumalı alanlarla genişleten nesneler sizin sorumluluğunuzdadır, sizin sorumluluğunuzdadır.

Bu nedenle, iyi belgelenmemiş korunan alanlar / yöntemler veya kullanıcılar bu tür alanların ve yöntemlerin nasıl kullanılması gerektiğini gerçekten anlamıyorlarsa, kendileri ve size gereksiz yere sorun yaşamaları için iyi bir şansa sahipler.

Öte yandan, çoğu şeyi özel yapmak, kullanıcıların esnekliğini azaltacaktır ve sadece bir şeyler yapmak için bir çatal oluşturmak ve muhafaza etmek istemeyebileceği için, korunmuş alternatifler aramaya bile devam edebilir.

Yani, özel, korunan ve halk arasında iyi bir denge gerçekten önemli olan.

Şimdi, özel ve korunan arasında karar vermek asıl sorun.

Korumalı ne zaman kullanılmalı?

Bir alanı ne zaman anlarsanız çok esnek olabilir, korunan olarak kodlanmalıdır. Bu esneklik: sıfır olmaktan (null'un her zaman istisnalar atmamak için geçerli bir durum olduğu kontrol edilir ve kabul edilir) sınıftan önce kullanılmadan önce kısıtlamalara sahip olmaktır. > = 0, <100 vb. Ve aşırı debi değerleri için otomatik olarak sabitlenir, en fazla bir uyarı mesajı atar.

Bu nedenle, böyle bir korumalı alan için bir alıcı oluşturabilir ve yalnızca onu (alan değişkenini kullanmak yerine) kullanmak yerine kullanabilirsiniz, diğer kullanıcılar kendi kodlarına göre daha fazla esneklik istemeleri durumunda kullanamazlar. : negatif değerlerin genişletilmiş sınıflarında iyi çalışmasını istiyorlarsa.


-1

imo @tdammers doğru değil ve aslında yanıltıcıdır.

Uygulama ayrıntılarını gizlemek için özel değişkenler vardır. Sınıfınız puanları saklamak Aiçin bir kullanıyor olabilir array. Yarın bir treeveya priority queueyerine kullanmak isteyebilirsiniz . Sınıfınızın ihtiyaç duyduğu tüm kullanıcılar puanları ve isimleri addScore()girmenin bir yolu ve ilk 10'un kim olduğunu anlamanın bir yoludur getTop(n).

Temel veri yapısına erişmeleri gerekmez. Kulağa hoş geliyor mu? Eh, bazı uyarılar var.

Zaten çok fazla devlet depolamamalısınız, çoğu gerekli değil. Saklama durumu, belirli bir sınıfa "ayrılmış" olsa bile kodunuzu karmaşıklaştıracaktır. Bir düşünün, bu özel değişken muhtemelen değişti çünkü başka bir nesne o sınıfın yöntemi olarak adlandırıldı. Bu yöntemin ne zaman ve nerede çağrıldığını ve bu ortak yöntemin teorik olarak herhangi bir yerde çağrılabileceğini öğrenmen gerekiyor.

Yapabileceğiniz en iyi şey, programınızın içerdiği durum miktarını sınırlamak ve mümkün olduğunda saf işlevleri kullanmaktır.


-1
  • Program çalışırken değerine erişen bir değişkene erişmek, özel bir değişken yapmak , kod çalışırken değerini korur .
  • "Veri gizleme" denilen nokta, dahili verileri sınıfı kullanan diğer sınıflardan gizli tutmaktır. Bu diğer sınıflar, doğrudan değişkenlerin değerlerini değiştirerek değil, sınıftaki yöntemleri çağırarak davranışa erişmelidir.
  • Değişkeni özel bir veri üyesi yaparak, değerin asla değişmemesi veya değişmemesini daha kolay sağlayabilirsiniz. Öte yandan, değişken genel ise, başka bir sınıf, kodun diğer bölümlerinin çökmesine neden olabilecek değeri değiştirebilir veya değiştirebilir.

1
Bu, önceki 17
cevapta

-4

Önce nesne yönelimli programlama kavramını anlamalısınız. Soyutlama, kapsülleme vb.

Soyutlama - Uygulamanın detaylarını vurgulamak zorunda kalmadan mantık fikrini elde edersiniz.

Kapsülleme - Nesnenin altını çizen uygulamayı göremezsiniz. Nesnenin genel arayüzünü sadece siz görebilirsiniz.

Şimdi özel uygulamada C #, Java, C ++ gibi nesne yönelimli programlardan biriyle bu kavramları uygulayabilirsiniz.

özel - Dış dünyadan gizlenmesi gereken uygulama. Böylece bunu değiştirebilir ve sınıfınızın kullanıcısı etkilenmez.

public - Bu, nesnenizi kullanabileceğiniz arabirimdir.


1
korumalı - doğrudan alt sınıflar (genişleticiler) (java) tarafından erişilebilir.
Kova Gücü
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.