Image

Imagelexicore wrote in Imageru_java

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

Вылезает ко мне в 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 и т.п. я в курсе. :)