Skip to content

Instantly share code, notes, and snippets.

@4e1e0603
Forked from tacoberu/intf.java
Last active December 2, 2016 18:54
Show Gist options
  • Save 4e1e0603/3d4197df0ca54cb02aeab79aab7e7177 to your computer and use it in GitHub Desktop.
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
/*
------------------------------------------------------------------------------
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