Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- This is only sort-of java. I've taken a few
- liberties with the syntax for sugar's sake.
- Of note is the syntax for simple getters and setters:
- The visibility of the getter is given by the
- first visibility modifier. Then after the
- identifier, the visibility of the setter
- is given, then the behavior of the setter.
- The setter takes as a parameter an object
- of the same type as the field it sets, and
- the name of that parameter is the same as
- the name of the field it sets. The setter
- shall return the value to assign to the
- field. Nontrivial getters and more complex
- setters must be built manually (their
- advanced behavior is an important part of
- their class's interface
- If no inline setter behavior is defined, no
- setter is automatically defined at all, and
- it must be built manually.
- If no inline setter behavior is defined, the
- getter-visibility modifier is a normal
- visibility modifier.
- If an inline setter visibility is specified,
- but no behavior is defined, it's assumed to
- be a "trivial" setter, and the behavior (for
- a field of name $name) is generated as
- {return $name;}
- If you want to specify package-visibility for
- a setter, use the already-existing package
- keyword
- */
- public class Main
- {
- public static void main(String... args)
- {
- /* I don't know the names of any kinds of panini, or
- the kinds of things that go them. */
- /* A "classic" style construction: Lots of params, no names.
- Even while writing this example, I forgot which order the
- params were in, and had to check the implementation.
- This method is very error-prone, because you could
- accidentally set a panino with fish for bread.*/
- Panino johns = new PaninoClassic("John", "Wheat", "Tuna",
- "Provalone", "Salami", "Lettuce", "Tomato", "Another vegetable");
- /* The classic Builder. It's a lot easier to call, and there's no
- risk of setting bread="tuna", but it took some boilerplate
- to implement the builder in the first place, and there's
- no guarantee you got every field. Also, you can have a panini
- with both meat and fish, which I assume violates business rules
- because it doesn't seem to be possible in the StepBuilder.*/
- Panino jerrys = new PaninoBuilder()
- .paninoCalled("Jerry")
- .setBreadType("Wheat")
- .setFish("Tuna")
- .setCheese("Provalone")
- .setMeat("Salami")
- .setVegetables("Vegetables")
- .build();
- /* The proposed stepbuilder. Safest of all, but absolutely horrific
- to implement. Plus, the hinting only helps if you're working in
- an IDE. I wrote this example from a POTE, and had to refer to the
- (ginormous) PaninoStepBuilder implementation over and over again
- to check I was doing everything in the right step. Also, it seems
- you can't have a panini with meat and fish. Whoops. I'll also
- take issue with his implementation of the panino class: If you're
- not allowed to have both meat and fish, and they are both fillings,
- you shouldn't give them each their own field, it should be
- String filling, or fish and meat should have a distinct type*/
- Panino jimmys = PaninoStepBuilder.newBuilder()
- .paninoCalled("Jimmy")
- .breadType("Wheat")
- .fish("Tuna")
- .withCheese("Provalone")
- .addVegetable("tomato")
- .addVegetable("lettuce")
- .noMoreVegetablesPlease()
- .build();
- /* Finally, the classic constructor with named parameters. Easy to write,
- easy to invoke. For very complicated classes with optional parameters,
- default values, and other nontrivial business rules, you should
- subclass.*/
- Panino jeffs = new PaninoClassic(
- name: "Jeff",
- bread:"Wheat",
- filling: "Tuna",
- cheese: "Provalone",
- vegetables: {"tomato","lettuce"});
- /* Closing thoughts: The PaninoStepBuilder is more of a burden than a
- * boon if you're not using an IDE. I was unable to exactly replicate
- * the behavior of the StepBuilder with only named params, but that's
- * mostly because the Panino class was flawed in its business logic. */
- }
- }
- public class Panino
- {
- private {
- final String name public;
- String breadType public;
- String fish public;
- String cheese public;
- String meat public;
- List<String> vegs public;
- }
- public Panino(String name)
- {
- this.name = name;
- }
- @Override
- public String toString()
- {
- return String.format("Panino [name=%s, breadType=%s,
- fish=%s, cheese=%s, meat=%s, vegetables=%s]",
- name, breadType, fish, cheese, meat, vegetables.toString());
- }
- }
- /** A classic builder, as supplied. */
- public class PaninoBuilder
- {
- private {
- String name;
- String breadType;
- String fish;
- String cheese;
- String meat;
- List vegetables = new ArrayList();
- }
- public PaninoBuilder paninoCalled(String name){
- this.name = name;
- return this;
- }
- public PaninoBuilder breadType(String breadType){
- this.breadType = breadType;
- return this;
- }
- public PaninoBuilder withFish(String fish){
- this.fish = fish;
- return this;
- }
- public PaninoBuilder withCheese(String cheese){
- this.cheese = cheese;
- return this;
- }
- public PaninoBuilder withMeat(String meat){
- this.meat = meat;
- return this;
- }
- public PaninoBuilder withVegetable(String vegetable){
- vegetables.add(vegetable);
- return this;
- }
- public Panino build()
- {
- Panino panino = new Panino(name);
- panino.setBreadType(breadType);
- panino.setCheese(cheese);
- panino.setFish(fish);
- panino.setMeat(meat);
- panino.setVegetables(vegetables);
- return panino;
- }
- }
- /** The example step-builder as supplied. I haven't
- * edited at all, because of how mad the amount of
- * typing would be to implement it myself.
- */
- public class PaninoStepBuilder
- {
- public static FirstNameStep newBuilder()
- {
- return new Steps();
- }
- private PaninoStepBuilder() {}
- /**
- * First Builder Step in charge of the Panino name.
- * Next Step available : BreadTypeStep
- */
- public static interface FirstNameStep
- {
- BreadTypeStep paninoCalled(String name);
- }
- /**
- * This step is in charge of the BreadType.
- * Next Step available : MainFillingStep
- */
- public static interface BreadTypeStep
- {
- MainFillingStep breadType(String breadType);
- }
- /**
- * This step is in charge of setting the main filling (meat or fish).
- * Meat choice : Next Step available : CheeseStep
- * Fish choice : Next Step available : VegetableStep
- */
- public static interface MainFillingStep
- {
- CheeseStep meat(String meat);
- VegetableStep fish(String fish);
- }
- /**
- * This step is in charge of the cheese.
- * Next Step available : VegetableStep
- */
- public static interface CheeseStep
- {
- VegetableStep noCheesePlease();
- VegetableStep withCheese(String cheese);
- }
- /**
- * This step is in charge of vegetables.
- * Next Step available : BuildStep
- */
- public static interface VegetableStep
- {
- BuildStep noMoreVegetablesPlease();
- BuildStep noVegetablesPlease();
- VegetableStep addVegetable(String vegetable);
- }
- /**
- * This is the final step in charge of building the Panino Object.
- * Validation should be here.
- */
- public static interface BuildStep
- {
- Panino build();
- }
- private static class Steps implements FirstNameStep, BreadTypeStep, MainFillingStep, CheeseStep, VegetableStep, BuildStep {
- private String name;
- private String breadType;
- private String meat;
- private String fish;
- private String cheese;
- private final List<String> vegetables = new ArrayList<String>();
- public BreadTypeStep paninoCalled(String name)
- {
- this.name = name;
- return this;
- }
- public MainFillingStep breadType(String breadType)
- {
- this.breadType = breadType;
- return this;
- }
- public CheeseStep meat(String meat)
- {
- this.meat = meat;
- return this;
- }
- public VegetableStep fish(String fish)
- {
- this.fish = fish;
- return this;
- }
- public BuildStep noMoreVegetablesPlease()
- {
- return this;
- }
- public BuildStep noVegetablesPlease()
- {
- return this;
- }
- public VegetableStep addVegetable(String vegetable)
- {
- this.vegetables.add(vegetable);
- return this;
- }
- public VegetableStep noCheesePlease()
- {
- return this;
- }
- public VegetableStep withCheese(String cheese)
- {
- this.cheese = cheese;
- return this;
- }
- public Panino build()
- {
- Panino panino = new Panino(name);
- panino.setBreadType(breadType);
- if (fish != null) {
- panino.setFish(fish);
- } else {
- panino.setMeat(meat);
- }
- if (cheese != null) {
- panino.setCheese(cheese);
- }
- if (!vegetables.isEmpty()) {
- panino.setVegetables(vegetables);
- }
- return panino;
- }
- }
- }
- public class PaninoClassic extends Panino
- {
- public PaninoClassic(String name, String bread, String cheese,
- String filling, String... vegetables)
- {
- super(name);
- setBreadType(bread);
- setCheese(cheese);
- setMeat(filling);
- List<String> vegs = new ArrayList<>();
- for(String s : vegetables) {
- vegs.add(s);
- }
- setVegetables(vegs);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement