11. Quale soluzione tra quelle proposte è “Open Closed” (ovvero consente l'estensione senza necessitare di modifiche)?
12.
13. @Pre("@value>=0") // dbc framework Contract4j public Natural(int value) { this.value=value; } public Natural(int value) { if (value<0) { throw new InitException("non negativo: "+value); } this.value=value; } oppure: Costruttore
14. Aspettative @Test public void zeroEqualsZero() { Natural zero = new Natural(0); Natural anotherZero = new Natural(0); Assert.assertEquals(zero,anotherZero); }
15. Soluzione 1 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass () != o. getClass ()) return false; Natural natural = (Natural) o; if (value != natural.value) return false; return true; } @Override public int hashCode() { return value; }
16. Soluzione 2 @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Natural)) return false; Natural natural = (Natural) o; if (value != natural.value) return false; return true; } @Override public int hashCode() { return value; }
17. Aspettative @Test public void zeroEqualsZero() { Natural zero = new Natural(0); Natural anotherZero = new Natural(0); Assert.assertEquals(zero,anotherZero); } Soluzione 1. equals con getClass() OK Soluzione 2. equals con instanceof OK
18.
19. “sì alle estensioni! no alle modifiche!” public class Relative extends Natural { @Pre // precondizione rilassata public Relative(int value) { this.value = value; } .... }
20. “sì alle estensioni! no alle modifiche!” public class Relative extends Natural { @Pre // precondizione rilassata public Relative(int value) { this.value = value; } .... } La precondizione è rilassata. Preconditions cannot be strengthened in a subtype. (Postconditions cannot be weakened in a subtype.)
21.
22.
23. Natural sotto insieme di Relative (o, che è lo stesso, è isomorfo ad un suo sottoinsieme)
24.
25. Natural sotto insieme di Relative (o, che è quasi lo stesso, è isomorfo ad un suo sottoinsieme)
26. Morfismo : (astrazione di un processo che trasforma una struttura astratta in un'altra mantenendo alcune caratteristiche "strutturali" della prima (wikipedia))
27.
28. Natural sotto insieme di Relative (o, che è quasi lo stesso, è isomorfo ad un suo sottoinsieme)
29. Morfismo : (astrazione di un processo che trasforma una struttura astratta in un'altra mantenendo alcune caratteristiche "strutturali" della prima (wikipedia))
31. Concretamente @Test public void testMixEquals() throws Exception { Natural unoNat = new Natural(1); Relative unoRel = new Relative(1); Assert.assertEquals(unoNat,unoRel); } Soluzione 1. equals con getClass() fallisce Soluzione 2. equals con instanceof va a buon fine
32. Concretamente @Test public void testMixEquals() throws Exception { Natural unoNat = new Natural(1); Relative unoRel = new Relative(1); Assert.assertEquals(unoNat,unoRel); } Sto sostituendo all'1 di Nat, l'1 di Rel (Liskov?)
33. if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T. Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T. L.S.P. Varie definizioni
34. Nuova estensione public class ColoredRelative extends Relative { public static String NEUTRO="neutro"; public static String GRIGIO="grigio"; public static String NERO="nero"; private static String DEFAULT=NEUTRO; protected String colore=DEFAULT; public ColoredRelative(int value) { super(value); } ...
35. Violazione transitività @Test public void testTransViolation() throws Exception { Relative due = new Relative(2); ColoredRelative dueNeuter = new ColoredRelative(2); ColoredRelative dueNero = new ColoredRelative(2,ColoredRelative.NERO); Assert.assertFalse(dueNero.equals(dueNeuter)); Assert.assertEquals(due,dueNeuter); Assert.assertEquals(due,dueNero); }