среда, 1 августа 2012 г.

pattern: Builder


Назначение
    Отделяет конструирование сложного объекта от его представления, так что в результате одного и того же процесса конструирования могут получаться разные представления.


Использование шаблона в JDK
(примеры частично взяты с этого ресурса)

    java.lang.StringBuilder#append() (unsynchronized)
    java.lang.StringBuffer#append() (synchronized)


-------------------------StringBuilder------------------------

public class StringBuilderTest {
    public static void main(String[] args) {
        String name = "Mike";
        int age = 45;
        StringBuilder builder = new StringBuilder(64);
        builder.append("Person[");        
        builder.append("name=");        
        builder.append(name);        
        builder.append(", age=");        
        builder.append(age);        
        builder.append("]");
        String str = builder.toString();
        System.out.println(str);
    }
}

--------------Strong Typed Fluent Interface---------------

-- From: Мартин Фаулер "Предметно-ориентированные языки программирования", Глава 32, "Expression Builder" 

-- Code:

public class ComputerBuilderTest {
    public static void main(String[] args) {
        Computer computer = new ComputerBuilder()
                .disk(500000000000L)
                .memory(8000000000L)
                .cpu("Intel")
                .build();
        System.out.println(computer);
    }
}

class ComputerBuilder implements $CMD {
    public $MD cpu(final String cpu) {
        return new $MD() {
            public $D memory(final long memory) {
                return new $D() {
                    public $ disk(final long disk) {
                        return new $() {
                            public Computer build() {
                                return new Computer(cpu, memory, disk);
                            }
                        };
                    }
                };
            }

            public $M disk(final long disk) {
                return new $M() {
                    public $ memory(final long memory) {
                        return new $() {
                            public Computer build() {
                                return new Computer(cpu, memory, disk);
                            }
                        };
                    }
                };
            }
        };
    }

    public $DC memory(final long memory) {
        return new $DC() {
            public $C disk(final long disk) {
                return new $C() {
                    public $ cpu(final String cpu) {
                        return new $() {
                            public Computer build() {
                                return new Computer(cpu, memory, disk);
                            }
                        };
                    }
                };
            }

            public $D cpu(final String cpu) {
                return new $D() {
                    public $ disk(final long disk) {
                        return new $() {
                            public Computer build() {
                                return new Computer(cpu, memory, disk);
                            }
                        };
                    }
                };
            }
        };
    }

    public $CM disk(final long disk) {
        return new $CM() {
            public $M cpu(final String cpu) {
                return new $M() {
                    public $ memory(final long memory) {
                        return new $() {
                            public Computer build() {
                                return new Computer(cpu, memory, disk);
                            }
                        };
                    }
                };
            }

            public $C memory(final long memory) {
                return new $C() {
                    public $ cpu(final String cpu) {
                        return new $() {
                            @Override
                            public Computer build() {
                                return new Computer(cpu, memory, disk);
                            }
                        };
                    }
                };
            }
        };
    }
}

interface $CMD {
    public $MD cpu(String cpu);
    public $DC memory(long memory);
    public $CM disk(long disk);
}

interface $CM {
    $M cpu(String cpu);
    $C memory(long memory);
}

interface $MD {
    $D memory(long memory);
    $M disk(long disk);
}

interface $DC {
    $C disk(long disk);
    $D cpu(String cpu);
}

interface $C {
    $ cpu(String cpu);
}

interface $M {
    $ memory(long memory);
}

interface $D {
    $ disk(long disk);
}

interface $ {
    Computer build();
}

class Computer {
    private String cpu;
    private long memory;
    private long disk;

    Computer(String cpu, long memory, long disk) {
        this.cpu = cpu;
        this.memory = memory;
        this.disk = disk;
    }

    @Override
    public String toString() {
        return "Computer[" +
                "cpu=" + cpu +
                ", memory=" + memory +
                ", disk=" + disk +
                ']';
    }
}