public class BuilderTest {
@Test
public void test() {
Programmer programmer = new Programmer.ProgrammerBuilder()
.setFirstName("F").setLastName("L")
.setCity("City").setZipCode("0000A").setAddress("Street 39")
.setLanguages(new String[] {"bash", "Perl"})
.setProjects(new String[] {"Linux kernel"}).build();
assertTrue("Programmer should be 'F L' but was '" + programmer + "'",
programmer.toString().equals("F L"));
}
}
class Programmer {
private String firstName;
private String lastName;
private String address;
private String zipCode;
private String city;
private String[] languages;
private String[] projects;
private Programmer(String fName, String lName, String addr, String zip, String city, String[] langs, String[] projects) {
this.firstName = fName;
this.lastName = lName;
this.address = addr;
this.zipCode = zip;
this.city = city;
this.languages = langs;
this.projects = projects;
}
public static class ProgrammerBuilder {
private String firstName;
private String lastName;
private String address;
private String zipCode;
private String city;
private String[] languages;
private String[] projects;
public ProgrammerBuilder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public ProgrammerBuilder setLastName(String lastName) {
this.lastName = lastName;
return this;
}
public ProgrammerBuilder setAddress(String address) {
this.address = address;
return this;
}
public ProgrammerBuilder setZipCode(String zipCode) {
this.zipCode = zipCode;
return this;
}
public ProgrammerBuilder setCity(String city) {
this.city = city;
return this;
}
public ProgrammerBuilder setLanguages(String[] languages) {
this.languages = languages;
return this;
}
public ProgrammerBuilder setProjects(String[] projects) {
this.projects = projects;
return this;
}
public Programmer build() {
return new Programmer(firstName, lastName, address, zipCode, city, languages, projects);
}
}
@Override
public String toString() {
return this.firstName + " "+this.lastName;
}
}
public class BeanDefinitionBuilder {
/**
* The {@code BeanDefinition} instance we are creating.
*/
private AbstractBeanDefinition beanDefinition;
// ... some not important methods for this article
// Some of building methods
/**
* Set the name of the parent definition of this bean definition.
*/
public BeanDefinitionBuilder setParentName(String parentName) {
this.beanDefinition.setParentName(parentName);
return this;
}
/**
* Set the name of the factory method to use for this definition.
*/
public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
this.beanDefinition.setFactoryMethodName(factoryMethod);
return this;
}
/**
* Add an indexed constructor arg value. The current index is tracked internally
* and all additions are at the present point.
* @deprecated since Spring 2.5, in favor of {@link #addConstructorArgValue}
*/
@Deprecated
public BeanDefinitionBuilder addConstructorArg(Object value) {
return addConstructorArgValue(value);
}
/**
* Add an indexed constructor arg value. The current index is tracked internally
* and all additions are at the present point.
*/
public BeanDefinitionBuilder addConstructorArgValue(Object value) {
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(
this.constructorArgIndex++, value);
return this;
}
/**
* Add a reference to a named bean as a constructor arg.
* @see #addConstructorArgValue(Object)
*/
public BeanDefinitionBuilder addConstructorArgReference(String beanName) {
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(
this.constructorArgIndex++, new RuntimeBeanReference(beanName));
return this;
}
/**
* Add the supplied property value under the given name.
*/
public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
this.beanDefinition.getPropertyValues().add(name, value);
return this;
}
/**
* Add a reference to the specified bean name under the property specified.
* @param name the name of the property to add the reference to
* @param beanName the name of the bean being referenced
*/
public BeanDefinitionBuilder addPropertyReference(String name, String beanName) {
this.beanDefinition.getPropertyValues().add(name, new RuntimeBeanReference(beanName));
return this;
}
/**
* Set the init method for this definition.
*/
public BeanDefinitionBuilder setInitMethodName(String methodName) {
this.beanDefinition.setInitMethodName(methodName);
return this;
}
// Methods that can be used to construct BeanDefinition
/**
* Return the current BeanDefinition object in its raw (unvalidated) form.
* @see #getBeanDefinition()
*/
public AbstractBeanDefinition getRawBeanDefinition() {
return this.beanDefinition;
}
/**
* Validate and return the created BeanDefinition object.
*/
public AbstractBeanDefinition getBeanDefinition() {
this.beanDefinition.validate();
return this.beanDefinition;
}
}
public class FactoryMethodTest {
@Test
public void test() {
Meal fruit = Meal.valueOf("banana");
Meal vegetable = Meal.valueOf("carrot");
assertTrue("Banana should be a fruit but is "+fruit.getType(), fruit.getType().equals("fruit"));
assertTrue("Carrot should be a vegetable but is "+vegetable.getType(), vegetable.getType().equals("vegetable"));
}
}
class Meal {
private String type;
public Meal(String type) {
this.type = type;
}
public String getType() {
return this.type;
}
// Example of factory method - different object is created depending on current context
public static Meal valueOf(String ingredient) {
if (ingredient.equals("banana")) {
return new Meal("fruit");
}
return new Meal("vegetable");
}
}
public class FactoryTest {
// Test method which is the client
@Test
public void test() {
Kitchen factory = new KitchenFactory();
KitchenMeal meal = factory.getMeal("P.1");
KitchenMeal dessert = factory.getDessert("I.1");
assertTrue("Meal's name should be 'protein meal' and was '"+meal.getName()+"'", meal.getName().equals("protein meal"));
assertTrue("Dessert's name should be 'ice-cream' and was '"+dessert.getName()+"'", dessert.getName().equals("ice-cream"));
}
}
// abstract factory
abstract class Kitchen {
public abstract KitchenMeal getMeal(String preferency);
public abstract KitchenMeal getDessert(String preferency);
}
// concrete factory
class KitchenFactory extends Kitchen {
@Override
public KitchenMeal getMeal(String preferency) {
if (preferency.equals("F.1")) {
return new FastFoodMeal();
} else if (preferency.equals("P.1")) {
return new ProteinMeal();
}
return new VegetarianMeal();
}
@Override
public KitchenMeal getDessert(String preferency) {
if (preferency.equals("I.1")) {
return new IceCreamMeal();
}
return null;
}
}
// abstract product
abstract class KitchenMeal {
public abstract String getName();
}
// concrete products
class ProteinMeal extends KitchenMeal {
@Override
public String getName() {
return "protein meal";
}
}
class VegetarianMeal extends KitchenMeal {
@Override
public String getName() {
return "vegetarian meal";
}
}
class FastFoodMeal extends KitchenMeal {
@Override
public String getName() {
return "fast-food meal";
}
}
class IceCreamMeal extends KitchenMeal {
@Override
public String getName() {
return "ice-cream";
}
}