Değişmeyenler nelerdir, nasıl kullanılabilirler ve hiç programınızda kullandınız mı?


48

Work at Coder okuyorum ve içinde değişmezler hakkında çok fazla konuşma var. Anladığım kadarıyla, değişmez bir ifadeden önce ve sonra tutan bir durumdur. Mantık dersimi doğru hatırlıyorsam, diğer şeylerin yanı sıra, bu döngünün doğru olduğunu kanıtlamada da faydalılar.

Açıklamam doğru mu, yoksa bir şey mi kaçırdım? Programında hiç kullandın mı? Ve eğer öyleyse, nasıl yararlandılar?



@Robert Harvey: Evet, sadece bunu okudum. Fakat bana öyle geliyor ki, değişmezler yalnızca bir şeyi kanıtlamaya çalıştığınız zaman işe yararlar. Bu doğru mu?
gablin

Bu benim anlayışım; Programınız hakkında aklınıza gelmeye çalıştığınızda, doğruluğunu kanıtlamak için.
Robert Harvey,

3
@ user9094: Bir iddia, çalışma zamanının belirli bir noktasında bir şeyin doğru olduğunu ve kodda temsil edildiğinin beyanıdır. Bir değişmez, her zaman geçerli olduğunda ve kodun kendisinde temsil edilmeyen her zaman doğru olacak bir ifadedir (iyi kurulmayı umar).
David Thornley

1
Değişmezler doğruluk kanıtlamak için gerçekten yararlıdır, ancak bu durumla sınırlı değildir. Ayrıca, savunma programlaması ve hata ayıklama sırasında kullanışlıdır. Sadece kodunuzun doğru olduğunu kanıtlamakla kalmazlar, kodla ilgili nedenlere yardımcı olurlar ve hataların kökene yakın konumlarını bulmalarına yardımcı olurlar.
Tuhaf,

Yanıtlar:


41

OOP'da değişmez, programın geçerli olması için bir nesnenin ömrü boyunca daima geçerli olması gereken bir iddialar kümesidir. Nesnenin halihazırda durumunu değiştiren bir yöntemi uygulamadığı zamanlarda yapıcının sonundan yıkıcının başlangıcına kadar geçerli olmalıdır.

Değişmezliğe örnek olarak, iki üye değişkeninden birinin boş olması gerekir. Ya da birinin belirli bir değeri varsa, o zaman diğeri için izin verilen değerler kümesi şudur ya da ...

Bazen değişmezin tutup tutmadığını kontrol etmek için nesnenin bir üye işlevini kullanırım. Böyle değilse, bir iddia ortaya atılır. Ve yöntem, nesneyi değiştiren her yöntemin başlangıcında ve çıkışında çağrılır (C ++ 'da, bu sadece bir satırdır ...)


11
Değişmeyenlerden bahsetmek için + 1'in bir yürütme yönteminin ortasında doğru olması gerekmez.
Tuhaf,

1
@Oddthinking Mümkün olduğunda olsa önlemek için en iyisidir. Değişmeyen bir duruma girmek kolay ve geri dönmeden önce her şeyi doğru şekilde geri yüklemeyi unutmak kolay olurdu. İstisnalar ayrıca size sorun çıkarabilir.
Alexander

3
@Alexander: Önemsiz olmayan değişmezler için, kaçınmak neredeyse imkansızdır. Bir yöntemde birden fazla değişkeni, cevapta açıklandığı şekilde güncellemeniz gerekiyorsa, yalnızca birinin güncellendiği ve değişmezin yanlış olduğu bir nokta vardır. Yenilerini eklemeden iyi kod yazmanın yeteri kadar kısıtlaması var.
Tuhaf,

@Sıkça Düşünüyorum Evet, bu genellikle kaçınılmazdır. Ancak, örneğin, mantıksal olarak birbirine ait bir grup değişken varsa (örneğin, bir dizi ve dizideki "seçilen" bir öğenin dizini), o zaman muhtemelen bunları bir türe ayırmaya değer. Oradan, dizinin veya türün mutasyonları, bu türün yeni bir örneğinin tek bir ataması olarak ifade edilebilir
Alexander

13

Şey, bu başlıkta gördüğüm şeyler harika, ama işte benim için çok faydalı olan bir 'değişmez' tanımım var.

Değişmeyen, programınızın yürütülmesi sırasında bir insana iletilebilecek, ancak derleyicinize iletilemeyen uyulması gereken herhangi bir mantıksal kuraldır.

Bu tanım yararlıdır, çünkü koşulları iki gruba ayırır: derleyicinin zorlamada güvenilir olabileceği ve kodbase ile hata yapmadan etkileşime girmeleri için katkıda bulunanlara belgelenmesi, tartışılması, yorumlanması veya başka şekilde iletilmesi gerekenler. .

Ayrıca, bu tanım faydalıdır, çünkü "Değişmezler Kötü" genellemesini kullanmanıza izin verir.

Örnek olarak, manuel şanzımanlı arabadaki vites değişmeyenleri önlemek için tasarlanmıştır. İstesem, her vites için bir kol ile bir şanzıman yapabilirdim. Bu kol ileri ("devrede") veya geri ("serbest bırakılmış") olabilir. Böyle bir sistemde şöyle belgelenebilecek bir “değişmez” yarattım:

"Farklı bir vitese takılmadan önce mevcut vitese takılmaması çok önemlidir. Aynı anda iki vitese de takmak, şanzımanı parçalayacak mekanik gerilmelere neden olacaktır.

Ve böylece, özensiz sürüş yüzünden kırılan yayınları suçlayabilir. Ancak modern otomobillerde, viteslerin arasında dönen tek bir çubuk kullanılır. Modern bir vites değiştirme otomobili üzerinde, aynı anda iki vitese geçmek mümkün olmayacak şekilde tasarlanmıştır.

Bu şekilde, iletimin 'değişmezi kaldırmak' için tasarlandığını söyleyebiliriz, çünkü kendisinin mantıksal kuralı ihlal edecek şekilde mekanik olarak yapılandırılmasına izin vermez.

Kodunuzdan çıkardığınız her çeşit değişmez bir gelişmedir, çünkü onunla çalışmanın bilişsel yükünü azaltır.


1
Bir değişmez, programınızın yürütülmesi sırasında uyulması gereken herhangi bir mantıksal kuralsa ve mantıksal kuralınız aynı anda iki dişlinin aynı anda bağlanamayacağı yönündeyse, o zaman iki dişlinin aynı anda bağlanamayacağı değişmez değildir. zaman? Bu değişmez olmadan, şanzımanınız aynı anda iki vitrinde olabilir ve bu nedenle kendini parçalayabilir. İlk olarak, tek bir çubuk değiştirici aslında bu değişmezi zorlamaz mı? İkincisi, neden bir değişmez doğası gereği iyi ya da kötü olsun ki?
Dustin Cleveland,

1
Otomobilin dişlileriyle karşılaştırılması benim için çok açık. Teşekkürler!
Marecky

"Değişmeyen, programınızın yürütülmesi sırasında bir insana iletilebilecek, ancak derleyicinize iletilemeyecek mantıklı bir kuraldır." - Bunu çok seviyorum, özlü ve hatırlaması kolay.
SıfırKnight

@DustinCleveland Bu örnekte, vites değiştirmenin ardındaki mekanizmaların kuralları zorlayan 'derleyici' olduğunu düşünüyorum; oysa bir olaya neden olabilecek sürücü, bilgiyi tüketmesi ve hatırlaması gereken birçok müşteriden biridir. "belgelendi, tartışıldı, yorumlandı veya başka şekilde iletildi."
ebernard

Mükemmel bir açıklama! Şimdi kodunuzda değişmeyenlerin neden kötü bir uygulama olduğunun nedenini gerçekten anlıyorum.
Ben C Wang

3

Değişmez (ortak anlamda), belirli bir zamanda veya programınız yürütülürken her zaman doğru olması gereken bazı koşullar anlamına gelir. Örneğin, PreConditions ve PostConditions, bir işlev çağrıldığında ve geri döndüğünde doğru olması gereken bazı koşulları belirtmek için kullanılabilir. Nesne değişmezleri, bir nesnenin var olduğu süre boyunca geçerli bir duruma sahip olması gerektiğini belirtmek için kullanılabilir. Sözleşme prensibine göre tasarım budur.
İnkarcıları gayrı resmi olarak kodda çek kullanarak kullandım. Ancak daha yakın zamanda , doğrudan değişmeyenleri destekleyen .Net kod sözleşmeleri kitaplığıyla oynuyorum .


3

At Coders At aşağıdaki alıntı dayanarak ...

Ama bir şeyi koruduğunu bilmediğini öğrendikten sonra, ah, eğer o değişmezi korursak o zaman kütük arama zamanı elde ederiz.

... Sanırım "değişmez" = "istenen etkiyi sağlamak için sürdürmek istediğiniz koşul".

Görünüşe göre değişmeyen, ince bir biçimde farklı olan iki duyuya sahip:

  1. Aynı kalan bir şey.
  2. Hedef X'e ulaşmak için aynı kalmaya çalıştığınız bir şey (yukarıdaki "günlük arama zamanı" gibi).

Yani 1 bir iddia gibi; 2 doğruluk, performans veya diğer özellikleri kanıtlamak için bir araç gibidir. 2 örneği için Wikipedia makalesine bakın (çözümün MU bulmacasına doğruluğunu ispatladı).

Aslında 3. değişmezlik hissi şudur:

0,3. Programın (veya modül veya fonksiyonun) yapması gerekenler; Başka bir deyişle, amacı.

Aynı Coders At Work röportajından:

Ancak büyük yazılımı yönetilebilir yapan şey, ne yapması gerektiği ve hangi şeylerin doğru olması gerektiği konusunda bazı küresel değişmezlere veya büyük resimli ifadelere sahip olmaktır.


1

Bir değişmez, programınızın mantığını dikte etmek için kullanılabilecek bir kural veya varsayım gibidir.

Örneğin, kullanıcı hesaplarını takip eden bir yazılım uygulamanız olduğunu varsayalım. Ayrıca, kullanıcının birden fazla hesaba sahip olabileceğini varsayalım, ancak hangi nedenle olursa olsun, bir kullanıcının ana hesabı ile "diğer ad" hesapları arasında ayrım yapmanız gerekir.

Bu bir DB kaydı veya başka bir şey olabilir, ancak şimdilik her kullanıcı hesabının bir sınıf nesnesi tarafından temsil edildiğini varsayalım.

class userAccount {private char * pUserName; private char * pParentAccountUserName;

...}

Değişmeyen, pParentAccountUserName öğesinin NULL veya boş olması durumunda bu nesnenin ana hesap olduğu varsayımı olabilir. Farklı hesap türlerini ayırt etmek için bu değişmezi kullanabilirsiniz. Farklı kullanıcı hesap türlerini ayırt etmek için muhtemelen daha iyi yöntemler vardır, bu nedenle değişmezlerin nasıl kullanılabileceğini göstermek için sadece bir örnek olduğunu unutmayın.


Değişmezler bir programın durumunu kontrol eder. Tasarım kararları değiller.
Xavier Nodet,

3
Değişmeyenler hiçbir şeyi kontrol etmiyor. Bir değişmezin DOĞRU veya YANLIŞ olup olmadığını görmek için programın durumunu kontrol edebilirsiniz, ancak değişmezlerin kendileri hiçbir şey "yapmaz".
Pemdas

2
Tipik olarak, C ++ 'da üye x gibi bir çeşit sınıf değişmezliği görürsünüz ki, 25'ten küçük ve 0'dan büyük olmalıdır. Bu değişmezdir. Bu değişmezliğe karşı yapılan herhangi bir kontrol iddiadır. Yukarıda sahip olduğum örnekte, değişmezim pParentAccountUserName NULL veya boşsa, o zaman bir ana hesaptır. Değişmezler kararlar için tasarlanmıştır.
Pemdas

PParentAccountUserName öğesinin NULL veya boş olması durumunda, bu nesnenin ana hesap olduğunu nasıl kontrol edersiniz? İfadeniz yalnızca null / boş bir değerin neyi temsil etmesi gerektiğini tanımlar. Değişmez, sistemin buna uygun olması, yani pParentAccountUserName öğesinin yalnızca bir ana hesap olması durumunda boş ya da boş olabileceğidir. Bu ince bir ayrım.
Cameron,

1

Fizik arkaplanından gelince, fizikte temel olarak bütün bir hesaplama / simülasyon boyunca değişmeyen miktarlar olan değişmezlerimiz var. Örneğin, fizikte kapalı bir sistem için toplam enerji korunur. Veya yine fizikte, eğer iki parçacık çarpışırsa, ortaya çıkan fragmanlar tam olarak başladıkları enerjiyi ve tam olarak aynı momentumu (vektör miktarı) içermelidir. Genellikle sonucu tam olarak belirtecek yeterli değişmez yoktur. Örneğin, 2 parçacıklı çarpışmada, dört değişmezimiz, üç momentum bileşeni ve bir enerji bileşenimiz var, ancak sistemin altı serbestlik derecesi var (durumunu tanımlamak için altı sayı). Değişmezler, yuvarlama hatası dahilinde korunmalıdır, ancak onların muhafazası çözümün doğru olduğunu kanıtlamaz.

Normalde, bu şeyler akıl sağlığı kontrolleri olarak önemlidir, ancak kendi başlarına doğruluğu kanıtlayamazlar.


1
-1 Fizikteki değişmezler farklıdır. Bir çözümü hesaplamak, bir algoritmanın doğru olduğunu kanıtlamakla aynı değildir. İkincisi için, değişmezler olabilir doğruluğu ispat.
aaronasterling
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.