Пятничный пост

May 18, 2007 17:03

Вылезает ко мне в ICQ приятель и говорит: анекдот мол слышал такой?

Жена - мужу-программеру:
Сходи в магазин
Купи буханку хлеба.
Если будут яйца - купи десяток.
Муж в магазине:
- Яйца есть?
- Есть.
- Тогда дайте десять буханок хлеба!

Cлышал, говорю. А он - а запрограммируй?

Я сначала думаю - что за ерунда? А потом решил - почему бы и нет?

Вот что вышло (на коленке, в первом приближении):

public void testAnekdot() {

final Person wife = new Person();
final Person husband = new Person();
final Shop shop = new Shop();
// Жена - мужу-программеру:
final Instructions instructions = wife.instruct(husband);
// Сходи в магазин
final ShopVisit visitShop = instructions.visit(shop);
// Купи буханку хлеба.
final Buying purchaseBread = visitShop.buy(new ProductLookup() {
public Product getProduct(Shop shop) {
return shop.lookup("bread");
}
}, new IntegerQuantityLookup(1));

// Если будут яйца - купи десяток.
visitShop.getCurrentBuying().setQuantityLookup(new QuantityLookup() {
public Number getQuantity(Shop shop) {
return shop.lookup("eggs") != null ? 10 : 1;
}
});

// - Яйца есть?
// - Есть.
// - Тогда дайте десять буханок хлеба!
final Collection
purchases = instructions.execute();

Assert.assertEquals(1, purchases.size());
final Purchase purchase = purchases.iterator().next();
Assert.assertEquals("bread", purchase.getProduct().getName());
Assert.assertEquals(10, purchase.getQuantity());

}

public static class Person {
public Instructions instruct(Person person) {
return new Instructions(this, person);
}
}

public static class Instructions {

private final Person instructor;

private final Person subordinate;

private final Collection actions = new LinkedList();

public Instructions(Person instructor, Person subordinate) {
this.instructor = instructor;
this.subordinate = subordinate;
}

public Person getInstructor() {
return instructor;
}

public Person getSubordinate() {
return subordinate;
}

public ShopVisit visit(Shop shop) {
final ShopVisit shopVisit = new ShopVisit(shop);
actions.add(shopVisit);
return shopVisit;
}

public Collection
execute() {
final Collection
purchases = new LinkedList
();
for (final ShopVisit shopVisit : actions) {
purchases.addAll(shopVisit.execute());
}
return purchases;
}
}

public static class Shop {

public Product lookup(String productName) {
// У нас типа все есть!
return new Product(productName);
}

public Purchase sell(Product product, Number quantity) {
// И в любых количествах!
return new Purchase(product, quantity);
}

}

public static class ShopVisit {
private final Shop shop;

private final Collection buyings = new LinkedList();

public ShopVisit(Shop shop) {
this.shop = shop;
}

public Collection
execute() {
final Collection
purchases = new LinkedList
();
for (Buying buying : buyings) {
purchases.add(buying.execute(shop));
}
return purchases;
}

private Buying currentBuying;

public Buying getCurrentBuying() {
return currentBuying;
}

public Buying buy(ProductLookup productLookup,
QuantityLookup quantityLookup) {
final Buying buying = new Buying(productLookup, quantityLookup);
buyings.add(buying);
this.currentBuying = buying;
return buying;
}
}

public static class Buying {

private final ProductLookup productLookup;

private QuantityLookup quantityLookup;

public Buying(ProductLookup productLookup, QuantityLookup quantityLookup) {
this.productLookup = productLookup;
this.quantityLookup = quantityLookup;
}

public ProductLookup getProductLookup() {
return productLookup;
}

public QuantityLookup getQuantityLookup() {
return quantityLookup;
}

public void setQuantityLookup(QuantityLookup quantityLookup) {
this.quantityLookup = quantityLookup;
}

public Purchase execute(Shop shop) {
final Product product = productLookup.getProduct(shop);
final Number quantity = quantityLookup.getQuantity(shop);
return shop.sell(product, quantity);
}
}

public static class Purchase {

private final Product product;

private final Number quantity;

public Purchase(Product product, Number quantity) {
this.product = product;
this.quantity = quantity;
}

public Product getProduct() {
return product;
}

public Number getQuantity() {
return quantity;
}
}

public static class Product {
private final String name;

public Product(String name) {
this.name = name;
}

public String getName() {
return name;
}
}

public interface ProductLookup {
public Product getProduct(Shop shop);
}

public interface QuantityLookup {
public Number getQuantity(Shop shop);
}

public static class IntegerQuantityLookup implements QuantityLookup {
private final int quantity;

public IntegerQuantityLookup(final int quantity) {
this.quantity = quantity;
}

public Number getQuantity(Shop shop) {
return quantity;
}
}

Про потенциальные NPE и т.п. я в курсе. :)
Previous post Next post
Up