( SzBlackY | 2016. 03. 20., v – 18:12 )

Például nem tudsz kétféle koszinuszfüggvény implementációt úgy csinálni, hogy ne egyezzen meg a kimenet.

+/- a contract-ben vállalt hibahatár (Math.cos: The computed result must be within 1 ulp of the exact result.)
Ha mindkettő tartja a hibahatárt, de az FPU-only valamivel pontatlanabb, attól még cserélhetők, ha bit szinten nem is ugyanazt hozzák (és hogy ez egy hosszabb számítás végére orbitális különbségeket jelenthet).

Ha egy EmailValidator.isValid() specifikációja csak annyi, hogy "Validálja az e-mail címet" akkor az egy gagyi specifikáció

Fentebb írtam egy specifikációt, hogy "akkor és csak akkor ad vissza igazat, ha nem tudja bizonyítani, hogy a megadott e-mail cím nem képes levelet fogadni". A User contractje eleve úgy szól [ugye a refaktorálás előtt még róla és az ő klienséről volt szó], hogy a felhasználó élő, érvényes e-mail címét tartalmazza, vagyis az, hogy ezt milyen szinten tartatod be (pont azért, mert nem tudod _ténylegesen_ betartatni) egy szerintem időben változtatható, akár cserélgethető implementációjú kérdés. A User contractjének viszont azt tartalmaznia kell, hogy a klienseinek fel kell készülnie, hogy az e-mail címet érvényesíti és elutasíthatja (még ha abban az időben, amikor az első kliense készül, a User a NoOp-ot használja is).

Az, hogy egy interfész formailag nem változik, attól még lehet inkompatibilis változás az API-ban: az API nem csak formaiság, szemantikája is van.

És itt kezdődik a parttalan jogászkodás, hogy mi számít inkompatibilis változásnak: ha bármi változik, vagy ha valami úgy változik, hogy a contract-ot többé nem tartja be bizonyos inputokra. Ha bevezetek egy AlwaysFalseEmailValidator-t és azt kezdi el használni a User, az egyértelműen egy inkompatibilis (bugos) változtatás, mivel korábban elfogadott, valid e-mail címeket többé nem fogad el. Ha viszont váltok az RFCValidator-ról a DomainValidator-ra, akkor annyiból inkompatibilis a változás, hogy a korábbi bar@example.foo-t használó unit test elhasal, viszont korábban pont a bar@example.foo-s unit teszt volt az, ami nem tartotta magát a User interfészhez (érvénytelen e-mail címet adott meg, akár szándékosan, akár nem).

Ha mondjuk egyik napon a hálózati áram 230 V helyett 450 V lenne, akkor hiába ugyanaz a csatlakozó és az aljzat (azaz formailag ugyanaz az interfész), szemantikailag nem ugyanolyan: bedugsz egy 230 V-ra méretezett eszközt és megsül.

Nem is ezt mondtam, hogy bármi előjel nélkül hirtelen kezdjünk el e-mailt validálni. Onnan indult az egész, hogy szerencsésebb kitenni a gettert/settert és ráírni, hogy dobhat Exception-t, ha invalid; vagyis az áram szolgáltató a nulladik naptól közölte, hogy amikor úgy gondolja ő válthat 450V-re, úgyhogy a kliens készüljön fel rá.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)