четверг, 18 августа 2011 г.

Ленивая инициализация. Пример кода


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public final class Person {
    private final int id;
    private final String name;
    private final Map knownPersons = new HashMap();
    
    public Person(int id, String name) {
        this.name = name;
        this.id = id;
    }
    
    /**
     * Метод возвращает объект персоны, с которой знакома данная персона
     * Если персоны еще не знакомы, то текущая персона знакомится и запоминает
     * В этом методе и есть весь смысл примера
     */
    public Person getKnownPerson(int id) {
        if (!knownPersons.containsKey(id)) {
            knownPersons.put(id, new Person(id, getNameById(id)));
        }
        return knownPersons.get(id);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (knownPersons.size() > 0) {
            Iterator iterator = knownPersons.keySet().iterator();
            while (iterator.hasNext()) {
                int key = iterator.next();
                Person person = knownPersons.get(key);
                sb.append(person.toString());
            }
        } else {
            sb.append("no known persons");
        }
        return "Person [id=" + id + ", name=" + name + ", knownPersons="
                + sb + "]";
    }

    private String getNameById(int id) {
        return id + "'s Name";
    }
    
    public static void main(String[] args) {
        Person person1 = new Person(1, "Вася Петя");
        Person person2 = person1.getKnownPerson(2);
        Person person3 = person1.getKnownPerson(3);
        System.out.println(person2.toString());
        System.out.println(person3.toString());
        System.out.println(person1.toString());
    }
}
/**
 * Output:
 * Person [id=2, name=2's Name, knownPersons=no known persons]
 * Person [id=3, name=3's Name, knownPersons=no known persons]
 * Person [id=1, name=Вася Петя, knownPersons=
 *     Person [id=2,name=2's Name, knownPersons=no known persons]
 *     Person [id=3, name=3's Name, knownPersons=no known persons]
 * ]
 */

четверг, 11 августа 2011 г.

Паттерн фабричный метод. Пример кода


//product
public interface MilkProduct {
    String getName();
    float getWeight();
}


//creator
//в абстрактном классе можно сделать процедуры по созданию продукта по умолчанию
//или какие-то общие действия
public abstract class MilkProductCreator {
    abstract public MilkProduct getProduct();
}


//concrete product
public class Butter implements MilkProduct {
    private float weight = 3.5f;
    final private static String NAME = "Масло";

    @Override
    public float getWeight() {
        return weight;
    }

    @Override
    public String getName() {
        return NAME;
    } 
}


//concrete product
public class SourCream implements MilkProduct {
    private float weight = 1.3f;
    final private static String NAME = "Сметана";

    @Override
    public float getWeight() {
        return weight;
    }

    @Override
    public String getName() {
        return NAME;
    }  
    
}


//concrete creator
public class ButterCreator extends MilkProductCreator {

    @Override
    public MilkProduct getProduct() {
        return new Butter();
    }

}


//concrete creator
public class SourCreamCreator extends MilkProductCreator {

    @Override
    public MilkProduct getProduct() {
        return new SourCream();
    }

}


public class Application {
    public static void main(String[] args) {
        
        MilkProductCreator[] milkProductCreators = {
            new ButterCreator(),
            new SourCreamCreator()
        };
        
        for (MilkProductCreator milkProductCreator : milkProductCreators) {
            MilkProduct milkProduct = milkProductCreator.getProduct();
            System.out.printf(
                "%s. Вес: %.1f кг\n",
                milkProduct.getName(), milkProduct.getWeight()
            );
        }
    }
}
/*
 * Output:
 * Сметана. Вес: 1,3 кг
 * Масло. Вес: 3,5 кг
 */



понедельник, 8 августа 2011 г.

Паттерн Builder (Строитель). Пример кода


/**
 * Интерфейс, описывающий части, из которых может состоять здание
 * Методы специально не сделаны абстрактными, что бы иметь возможность
 * не строить ненужные части здания
 */
public abstract class Builder {
    public void buildFundament() {
        
    }
    
    public void buildFloor() {
        
    }
    
    public void buildRoof() {
        
    }
    
    public void buildBasement() {
        
    }
    
    abstract Object getBuilding();
}


public class FrameHouseBuilder extends Builder {   
    private FrameHouse fh = new FrameHouse();
    
    public void buildFundament() {
        fh.setPart("Фундамент. ");
    }
    
    public void buildFloor() {
        fh.setPart("1 этаж. ");
    }
    
    public void buildRoof() {
        fh.setPart("Двускатная крыша. ");
    }

    @Override
    public FrameHouse getBuilding() {
        return fh;
    }
}


public class OfficeBuildingBuilder extends Builder {
    private OfficeBuilding ob = new OfficeBuilding();
    private int floors = 0;
    
    public void buildFundament() {
        ob.setPart("Фундамент. ");
    }
    
    public void buildBasement() {
        ob.setPart("Подвал. ");
    }
    
    public void buildFloor() {
        floors++;
        ob.setPart(floors + " этаж. ");
    }
    
    public void buildRoof() {
        ob.setPart("Плоская крыша. ");
    }

    @Override
    public OfficeBuilding getBuilding() {
        return ob;
    }
}


public class FrameHouse {
    
    private StringBuilder parts = new StringBuilder();
    
    public void setPart(String part) {
        parts.append(part);
    }
    
    public String getParts() {
        return parts.toString();
    }
}


public class OfficeBuilding {
    private StringBuilder parts = new StringBuilder();
    
    public void setPart(String part) {
        parts.append(part);
    }
    
    public String getParts() {
        return parts.toString();
    }
}


/**
 * Распорядитель. Собирает различные виды зданий
 */
public class Director {
    public static FrameHouse getFrameHouse() {
        FrameHouseBuilder fhb = new FrameHouseBuilder();
        fhb.buildFundament();
        fhb.buildFloor();
        fhb.buildRoof();
        return fhb.getBuilding();
    }
    
    public static OfficeBuilding getOfficeBuilding() {
        OfficeBuildingBuilder fhb = new OfficeBuildingBuilder();
        fhb.buildBasement();
        fhb.buildFundament();
        for (int i=0; i < 5; i++) {
            fhb.buildFloor();
        }
        fhb.buildRoof();
        return fhb.getBuilding();
    }
}


public class Application {
    public static void main(String[] args) {
        
        FrameHouse fh = Director.getFrameHouse();
        System.out.println(fh.getParts());
        
        OfficeBuilding ob = Director.getOfficeBuilding();
        System.out.println(ob.getParts());
    }
}
/*
 * Output:
 * Фундамент. 1 этаж. Двускатная крыша. 
 * Подвал. Фундамент. 1 этаж. 2 этаж. 3 этаж. 4 этаж. 5 этаж. Плоская крыша. 
 */

Абстрактная фабрика. Пример кода


public interface GuiFactory {
    Button createButton();
    Checkbox createCheckbox();
}

public interface Button extends Cloneable {
    void click();
    Button clone();
}

public interface Checkbox extends Cloneable {
    void check();
    Checkbox clone();
}

public class NixButton implements Button {
    @Override
    public void click() {
        System.out.println("NixButton clicked");
    }
   
    @Override
    public Button clone() {
        return new NixButton();
    }
}

public class WinButton implements Button {
    @Override
    public void click() {
        System.out.println("WinButton clicked");
    }
   
    @Override
    public Button clone() {
        return new WinButton();
    }
}

public class NixCheckbox implements Checkbox {
    @Override
    public void check() {
        System.out.println("NixCheckbox checked");
    }
   
    @Override
    public Checkbox clone() {
        return new NixCheckbox();
    }
}

public class WinCheckbox implements Checkbox {
    @Override
    public void check() {
        System.out.println("WinCheckbox checked");
    }
   
    @Override
    public Checkbox clone() {
        return new WinCheckbox();
    }
}

public class NixGuiFactory implements GuiFactory{
    @Override
    public Button createButton() {
        return new NixButton();
    }
   
    @Override
    public Checkbox createCheckbox() {
        return new NixCheckbox();
    }
}

public class WinGuiFactory implements GuiFactory {
    @Override
    public Button createButton() {
        return new WinButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new WinCheckbox();
    }
}

public enum GuiTypes {
    WIN, NIX
}

final public class GuiCreator {
    final Button button;
    final Checkbox checkbox;
   
    public GuiCreator(GuiFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }
   
    public Button getNewButton() {
        return button.clone();
    }
   
    public Checkbox getNewCheckbox() {
        return checkbox.clone();
    }
}

public class Application {
    public static void main(String args[]) {
        GuiTypes guiType = GuiTypes.WIN;
        GuiFactory factory = null;
       
        switch (guiType) {
            case NIX:
                factory = new NixGuiFactory();
                break;
            case WIN:
                factory = new WinGuiFactory();
                break;
            default:
                throw new IllegalStateException();
        }
       
        GuiCreator guiCreator = new GuiCreator(factory);
        Button button = guiCreator.getNewButton();
        Checkbox checkbox = guiCreator.getNewCheckbox();
        button.click();
        checkbox.check();
    }
}

Делегирование. Пример кода


public class Hands {
    public void chop() {
        System.out.println("Рубить");
    }
}

public class Legs {
    public void jump() {
        System.out.println("Прыгать");
    }
}

public class Man {
    private Hands hands = new Hands();
    private Legs legs = new Legs();
   
    public void chop() {
        hands.chop();
    }
   
    public void jump() {
        legs.jump();
    }
}

пятница, 5 августа 2011 г.

Immutable-класс. Пример кода

Решил, что буду в метро, вместо творческой литературы изучать шаблоны проектирования, а что бы лучше усвоился материал, писать потом по памяти свой пример. Описание паттернов выкладывать не буду, только код.


import java.util.Date;

public final class ImmutableTest {
    private final String name;
    private final Date dateOfBirth;
    private final String[] skills;

    public ImmutableTest(String name, Date dateOfBirth, String... skills) {
        this.name = name;
        /*при конструировании объекта, полям присваиваются новые объекты,
         *вместо ссылок
         */
        this.dateOfBirth = new Date(dateOfBirth.getTime());
        this.skills = skills.clone();
    }

    public String getName() {
        return name;
    }

    /*
     * Возвращаем новый объект Date, вместо передачи ссылки на текущий
     */
    public Date getDateOfBirth() {
        return new Date(dateOfBirth.getTime());
    }

    /*
     * Возвращаем клонированный массив, вместо ссылки на объект массива
     */
    public String[] getSkills() {
        return skills.clone();
    }
}

понедельник, 1 августа 2011 г.