[Design Pattern] Erzeugende Muster: Builder


Thomas Darimont

Premium-User
Hallo,

dieser Beitrag erklärt das erzeugende Muster: Builder
Java:
package de.tutorials.design.patterns.creational;

import java.util.LinkedHashSet;
import java.util.Set;

import org.jpatterns.gof.BuilderPattern.Builder;
import org.jpatterns.gof.BuilderPattern.ConcreteBuilder;
import org.jpatterns.gof.BuilderPattern.Director;
import org.jpatterns.gof.BuilderPattern.Product;

import static de.tutorials.design.patterns.creational.BuilderPatternExample.TeamBuilder.newTeam;

public class BuilderPatternExample {

  public static void main(String[] args) {
    Team dreamTeam = new Coach().makeNewTeam(newTeam());
                 
    System.out.println(dreamTeam);
  }

  @Builder
  public static interface ITeamBuilder{
    Team get();
    ITeamBuilder challenge();
    ITeamBuilder educate();
    ITeamBuilder motivate();
    ITeamBuilder add(Member member);
  }
  
  @ConcreteBuilder
  public static class TeamBuilder implements ITeamBuilder{

    protected Team team = new Team();

    public ITeamBuilder add(Member member) {
      team.members.add(member);
      return this;
    }

    public ITeamBuilder motivate() {
      team.motivation = new Motivation();
      return this;
    }

    public ITeamBuilder educate() {
      team.knowhow = new Knowhow();
      return this;
    }

    public ITeamBuilder challenge() {
      team.spirit = new Spirit();
      return this;
    }

    public Team get() {
      try {
        return team;
      } finally {
        team = null;
      }
    }

    public static ITeamBuilder newTeam() {
      return new TeamBuilder();
    }
  }

  static class TeamComponent{
    public String toString() {
      return getClass().getSimpleName() +": " + hashCode();
    }
  }
  
  static class Spirit extends TeamComponent {}
  static class Motivation extends TeamComponent {}
  static class Knowhow extends TeamComponent {}
  static class Member extends TeamComponent {}

  @Product
  static class Team {
    protected Set<Member> members = new LinkedHashSet<BuilderPatternExample.Member>();
    protected Spirit spirit;
    protected Motivation motivation;
    protected Knowhow knowhow;

    @Override
    public String toString() {
      return "Team [members=" + members + ", spirit=" + spirit + ", motivation=" + motivation + ", knowhow="
        + knowhow + "]";
    }
  }
  
  @Director
  static class Coach{
    public Team makeNewTeam(ITeamBuilder builder){
      Team team = TeamBuilder
      .newTeam()
        .add(new Member())
        .add(new Member())
        .add(new Member())
        .add(new Member())
        .add(new Member())
      .motivate()
      .educate()
        .add(new Member())
      .challenge()
      .get();
      return team;
    }
  }
}
Ausgabe:
Code:
Team [members=[Member: 1169863946, Member: 1690552137, Member: 1901116749, Member: 1807500377, Member: 355165777, Member: 778966024], spirit=Spirit: 1383884648, motivation=Motivation: 1701381926, knowhow=Knowhow: 1381270477]

Gruß Tom
 

Thomas Darimont

Premium-User
Hallo,

als Beispiel für den Einsatz des Builder Patterns in der Praxis hier die aus einer Google Protocol Buffers (http://code.google.com/p/protobuf/) Protokoll-Definition:

Forum.proto:
Code:
package de.tutorials;

option java_package = "de.tutorials.forum.model";
option java_outer_classname="ForumModel";

message Forum{
		required string id = 1;
		required string name = 2;
		
		message Thread{
			required string id = 1;
			required string name = 2;
			
			message Post{
				required string name = 1;
				required string poster = 2;
				required string content = 3;
			}
			
			repeated Post post = 3;
		}
		
		repeated Thread thead = 3;
}

message ForumBoard{
	required string name = 1;
	
	repeated Forum forum = 2;
}
... mittels ...
Code:
C:\development\java\google\protobuf>protoc.exe --java_out=. Forum.proto
... generierter API ...

Java:
package de.tutorials.forum.model;

import de.tutorials.forum.model.ForumModel.Forum;
import de.tutorials.forum.model.ForumModel.ForumBoard;

public class ForumModelBuilderPatternExample {

	public static void main(String[] args) {
		ForumBoard board = ForumBoard
				.newBuilder()
				.setName("tutorials.de")
				.addForum(
						Forum.newBuilder()
								.setId("1")
								.setName("Java")
								.addThead(
										Forum.Thread
												.newBuilder()
												.setId("4711")
												.setName("Builder Pattern")
												.addPost(
														Forum.Thread.Post
																.newBuilder()
																.setPoster("Thomas Darimont")
																.setName("Beispiel")
																.setContent("Von google Protocol Buffers generierters Beispiel zum Builder Pattern")
																.build()
														).build()
										   ).build()
							).build();

		System.out.println(board);
	}
}
Ausgabe:
Code:
name: "tutorials.de"
forum {
  id: "1"
  name: "Java"
  thead {
    id: "4711"
    name: "Builder Pattern"
    post {
      name: "Beispiel"
      poster: "Thomas Darimont"
      content: "Von google Protocol Buffers generierters Beispiel zum Builder Pattern"
    }
  }
}
Gruß Tom