-
-
Save 4e1e0603/3d4197df0ca54cb02aeab79aab7e7177 to your computer and use it in GitHub Desktop.
Příklad zadaný v diskuzi na devel.cz: http://devel.cz/otazka/prechod-z-c-na-c-nebo-na-javu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
------------------------------------------------------------------------------ | |
Popis: | |
Úkolem bylo ukázat, jak vytáhnout různá ověření na atributy osoby mimo samotnou | |
třídu osoba. Osoba zná svůj věk, ale neví jestli je plnoletá či smí na horskou dráhu. | |
Takové omezení přichází až z vnějšku a je závislé na kontextu, např. plnoletost je | |
jinak definována v USA než v EU. | |
1) Bude mít rozšíření které ověří, jestli osoba smí pít alkohol (min. 18 let). | |
2) Bude mít rozšíření, které ověří, jestli osoba může na horskou dráhu (min. 130cm a 40kg). | |
kompilace: `javac PersonPolicyServiceExample.java` | |
spuštění: `java PersonPolicyServiceExample` | |
------------------------------------------------------------------------------ | |
*/ | |
public final class PersonPolicyServiceExample | |
{ | |
public static boolean canDrinkAlcohol(HumanLike entry) { | |
return CanDrinkAlcoholSpecification.isSatisfiedBy(entry); | |
} | |
public static boolean canUseRollercoaster(HumanLike entry) { | |
return CanUseRollercoasterSpecification.isSatisfiedBy(entry); | |
} | |
public static void main(String[] args) { | |
HumanLike person1 = new Person(18, 180, 80); | |
HumanLike person2 = new Person(8, 129, 39); | |
boolean result1 = canDrinkAlcohol(person1); | |
boolean result2 = canDrinkAlcohol(person2); | |
assert(result1); // může pít | |
assert(!result2); // nemůže pít | |
System.out.println("První osoba může pít alkohol, druhá nikoliv!"); | |
boolean result3 = canUseRollercoaster(person1); | |
boolean result4 = canUseRollercoaster(person2); | |
assert(result1); // může na horskou dráhu | |
assert(!result2); // nemůže na horskou dráhu | |
System.out.println("První osoba může na horskou dráhu, druhá nikoliv!"); | |
} | |
} | |
/** | |
* Reprezentuje věk objektu, pro jednoduchost počítáno na roky, bez omezení | |
* na horní hranici; může jít tedy i o věk neživého objektu. | |
*/ | |
abstract class Age { | |
private static final int MIN_VALUE = 0; | |
private int years; | |
public Age(int years) { | |
assert(years >= MIN_VALUE); | |
this.years = years; | |
} | |
public int getYears() { | |
return this.years; | |
} | |
public static int getMin() { | |
return Range.MIN_VALUE; | |
} | |
} | |
/** | |
* Reprezentuje věk v liském měřítku, je tedy rozumně omezen shora. | |
*/ | |
final class HumanAge extends Age { | |
private static final int MAX_VALUE = 130; | |
public HumanAge(int years) { | |
super(years); | |
assert(years <= MAX_VALUE); | |
} | |
public static int getMax() { | |
return MAX_VALUE; | |
} | |
} | |
/** | |
* Představuje objekt, který má věk. | |
* <T> věk s rozumným omezním shora pro danou rodinu objektů. | |
*/ | |
interface Ageable<T extends Age> { | |
T getAge(); | |
} | |
class HumanWeight { | |
private final int value; | |
public HumanWeight(int kilograms) { | |
assert(kilograms >= 0); | |
this.value = kilograms; | |
} | |
public int getKilograms() { | |
return value; | |
} | |
} | |
class HumanHeight { | |
private final int value; | |
public HumanHeight(int centimeters) { | |
this.value = centimeters; | |
} | |
public int getCentimeters() { | |
return value; | |
} | |
} | |
/** | |
* Představuje člověka. | |
*/ | |
interface HumanLike extends Ageable<HumanAge> { | |
HumanAge getAge(); | |
HumanHeight getHeight(); | |
HumanWeight getWeight(); | |
} | |
/** | |
* Doménový model pro osobu. | |
*/ | |
class Person implements HumanLike { | |
private HumanAge age; | |
private HumanHeight height; | |
private HumanWeight weight; | |
public Person(int years, int height, int weight) { | |
this.age = new HumanAge(years); | |
this.height = new HumanHeight(height); | |
this.weight = new HumanWeight(weight); | |
} | |
public HumanAge getAge() { | |
return age; | |
} | |
public HumanHeight getHeight() { | |
return height; | |
} | |
public HumanWeight getWeight() { | |
return weight; | |
} | |
// Osoba má samozřejmě další metody, které tu nevypisujeme | |
// -- nejsme příznicvi anémického modelu :D | |
} | |
// Jednoduchá (čti naivní) implementace *specification pattern*. | |
/** | |
* Specifikace pro ověření, jestli osoba může pít alkohol. | |
*/ | |
final class CanDrinkAlcoholSpecification { | |
static boolean isSatisfiedBy(HumanLike candidate) { | |
return candidate.getAge().getYears() >= 18; | |
} | |
} | |
/** | |
* Specifikace pro oveření, jestli osoba může jezdit na horské dráze. | |
*/ | |
final class CanUseRollercoasterSpecification { | |
static boolean isSatisfiedBy(HumanLike candidate) { | |
return candidate.getWeight().getKilograms() >= 40 | |
&& candidate.getHeight().getCentimeters() >= 130; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment