Fluent Interface

Fluent Interface example using Java generics

public class Demo {
	@Test
	public void genericTest() {

		Cake<String> cake = new Cake<String>()
			.prepare()
			.addFlour()
			.addSugar()
			.addSecretIngredient("Yogurt")
			.mix()
			.bake();

		Pizza<String> pizza = new Pizza<String>()
			.prepare()
			.addSauce()
			.addCheese()
			.addTopping("Bacon")
			.addSecretIngredient("Arugula")
			.addTopping("Clams")
			.bake();

		cake.eat();
		pizza.eat();
	}
}
@SuppressWarnings("unchecked")
@FunctionalInterface
public interface Factory<E extends Factory<E>> {

    E bake();

	default E prepare() {
		System.out.println("preparing the kitchen");
		return (E) this;
	}

	default E eat() {
		String string = new StringBuilder()
			.append("Mmm, this ").append(this.getClass().getSimpleName())
		    .append(" is so tasty!")
			.toString();

		System.out.println(string);
		return (E) this;
	}
}
public abstract class Ingredient<E extends Ingredient<E, T>, T> implements Factory<E> {

	@SuppressWarnings("unchecked")
	public E addSecretIngredient(T ingredient) {
		System.out.println("adding some " + ingredient);
		return (E) this;
	}
}
public class Cake<T> extends Ingredient<Cake<T>, T> {

	public Cake<T> addSugar() {
		System.out.println("adding sugar");
		return this;
	}

	public Cake<T> addFlour() {
		System.out.println("adding flour");
		return this;
	}

	public Cake<T> mix() {
		System.out.println("mixing");
		return this;
	}

	public Cake<T> bake() {
		System.out.println("baking at 325 degrees");
		return this;
	}
}
public class Pizza<T> extends Ingredient<Pizza<T>, T> {

	public Pizza<T> addCheese() {
		System.out.println("adding cheese");
		return this;
	}

	public Pizza<T> addSauce() {
		System.out.println("adding sauce");
		return this;
	}

	public Pizza<T> addTopping(T topping) {
		System.out.println("putting some " + topping + " on top");
		return this;
	}

	public Pizza<T> bake() {
		System.out.println("baking at 450 degrees");
		return this;
	}
}