Guest User

DSL monster builder

a guest
Aug 2nd, 2014
210
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     package monster2;
  2.  
  3.     import java.util.Date;
  4.  
  5.     import mandatory.PersonCtors;
  6.     import mandatory.PersonGotBuilderStaticCtors.Data;
  7.     import mandatory.PersonGotBuilderStaticCtors.GotFirstName;
  8.     import mandatory.PersonGotBuilderStaticCtors.GotHairColor;
  9.     import mandatory.PersonGotBuilderStaticCtors.GotLastName;
  10.     import mandatory.PersonGotBuilderStaticCtors.GotMiddleName;
  11.     import mandatory.PersonGotBuilderStaticCtors.GotOptional;
  12.     import mandatory.PersonGotBuilderStaticCtors.GotRequire;
  13.  
  14.     /**
  15.      * Guides the adding of fields to make a person object. <br><br>
  16.      *
  17.      * Call doRequired() to start and doBuild() to finish
  18.      */
  19.     public class PersonBuilder {
  20.  
  21.        
  22.         // -- Required -- //
  23.  
  24.         private String   mFirstName;
  25.         private String   mMiddleName;
  26.         private String   mLastName;
  27.         private String   mNickName;
  28.         private String   mMaidenName;
  29.         private String   mEyeColor;
  30.         private String   mHairColor;
  31.         private Date     mDateOfBirth;
  32.         private String[] mAliases;
  33.        
  34.        
  35.         // -- Required Alternatives -- //  
  36.            
  37.         //Not both; not neither
  38.         private int      mBeersToday;     //One or
  39.         private String   mHowDrunk;       //the other
  40.        
  41.        
  42.        
  43.         // .==== Using persons setters instead ====. //
  44.  
  45.        
  46.         // -- Optional -- //
  47.  
  48.         //private String   mClothing;
  49.         //private String   mTattoo;
  50.            
  51.        
  52.         // -- Optional Alternatives -- //
  53.  
  54.         //Not both; either or neither
  55.         //private String   mFavoriteBeer;   //Either
  56.         //private String   mJobTitle;       //Or
  57.  
  58.  
  59.         // '=======================================' //
  60.        
  61.  
  62.        
  63.         // -- What all the fuss is about -- //
  64.  
  65.         private Person   mPerson;
  66.        
  67.        
  68.         // -- Builder interface -- //
  69.  
  70.         /** Call each required method in order offered.*/
  71.         public GotRequired doRequired() {
  72.             return new GotRequired();
  73.         }
  74.  
  75.         /*
  76.          * Required constructor values
  77.          *
  78.          * Enforce initialization with type driven state machine
  79.          *
  80.          * Each Got... is a state.  Each add... is a transition
  81.          * Using a tree of states.  Forking is fine but merging is not.
  82.          * Tree allows the builds at the end of the paths to know each state visited.
  83.          * Also allows states take the name of their one incoming transition.
  84.          *
  85.          * This creates a need to duplicate boiler plate code if forking happens early.  
  86.          * If a reordered presentation is acceptable put forking at the end
  87.          * for simpler paths.  
  88.          *
  89.          * Otherwise after the fork, where you might have merged, instead create
  90.          * duplicate states.  This will preserve memory of the fork and lead to the
  91.          * proper constructor.
  92.          *
  93.          * Using this pattern any combination of constructors and setters should
  94.          * be able to be supplied with values using this method.
  95.          *
  96.          */
  97.        
  98.         public class GotRequired {
  99.             public GotFirstName addFirstName(String firstName) {
  100.                 mFirstName = firstName;
  101.                 return new GotFirstName();
  102.             }
  103.         }
  104.        
  105.         public class GotFirstName {
  106.             public GotMiddleName addMiddleName(String middleName) {
  107.                 mMiddleName = middleName;
  108.                 return new GotMiddleName();
  109.             }
  110.         }
  111.        
  112.         public class GotMiddleName {
  113.             public GotLastName addLastName(String lastName) {
  114.                 mLastName = lastName;
  115.                 return new GotLastName();
  116.             }
  117.         }
  118.  
  119.         public class GotLastName {
  120.             public GotNickName addNickName(String nickName) {
  121.                 mNickName = nickName;
  122.                 return new GotNickName();
  123.             }
  124.         }
  125.        
  126.         public class GotNickName {
  127.             public GotMaidenName addMaidenName(String maidenName) {
  128.                 mMaidenName = maidenName;
  129.                 return new GotMaidenName();
  130.             }
  131.         }
  132.  
  133.         public class GotMaidenName {
  134.             public GotEyeColor addEyeColor(String eyeColor) {
  135.                 mEyeColor = eyeColor;
  136.                 return new GotEyeColor();
  137.             }
  138.         }
  139.  
  140.         public class GotEyeColor {
  141.             public GotHairColor addHairColor(String hairColor) {
  142.                 mHairColor = hairColor;
  143.                 return new GotHairColor();
  144.             }
  145.         }
  146.  
  147.         public class GotHairColor {
  148.             public GotDateOfBirth addDateOfBirth(Date dateOfBirth) {
  149.                 mDateOfBirth = dateOfBirth;
  150.                 return new GotDateOfBirth();
  151.             }
  152.         }
  153.  
  154.         public class GotDateOfBirth {
  155.             public GotAliases addAliases(String... aliases) {
  156.                 mAliases = aliases;
  157.                 return new GotAliases();
  158.             }
  159.         }
  160.  
  161.         public class GotAliases {
  162.             /** Controls alternatives that choose constructors */
  163.             public GotRequiredAlternatives doRequiredAlternatives(){
  164.                 return new GotRequiredAlternatives();
  165.             }
  166.         }  
  167.        
  168.         /*
  169.            .addAlternatives()          //Either x or y. a, b, or c. etc.
  170.                .addBeersToday(3)       //Now can't call addHowDrunk("Hammered");
  171.                .addFavoriteBeer("Duff")//Now can’t call addJobTitle("Safety Inspector");  
  172.  
  173.            .addBuild();                //Calls different constructors based on alternatives
  174.  
  175.         */
  176.        
  177.         /** Now the interesting forking bit */
  178.         public class GotRequiredAlternatives {
  179.             public GotPerson addBeersToday(int beersToday){
  180.                 mBeersToday = beersToday;
  181.  
  182.                 //Got enough for constructor
  183.                 mPerson = new Person(
  184.                         mFirstName,
  185.                         mMiddleName,
  186.                         mLastName,
  187.                        
  188.                         mNickName,                        
  189.                         mMaidenName,
  190.                         mEyeColor,  
  191.                         mHairColor,  
  192.                         mDateOfBirth,
  193.                         mBeersToday, //GotBeersToday
  194.                         mAliases);
  195.                    
  196.                 return new GotPerson();
  197.             }        
  198.  
  199.             public GotPerson addHowDrunk(String howDrunk){
  200.                 mHowDrunk = howDrunk;
  201.  
  202.                 //Got enough for constructor
  203.                 mPerson = new Person(
  204.                         mFirstName,
  205.                         mMiddleName,
  206.                         mLastName,
  207.                        
  208.                         mNickName,                        
  209.                         mMaidenName,
  210.                         mEyeColor,  
  211.                         mHairColor,  
  212.                         mDateOfBirth,
  213.                         mHowDrunk, //GotHowDrunk
  214.                         mAliases);
  215.                    
  216.                 return new GotPerson();
  217.             }        
  218.         }
  219.        
  220.         //Could have created GotHowDrunk and GotBeersToday
  221.         //but we're past the constructor choice so we can
  222.         //forget the path that brought us here.
  223.        
  224.         public class GotPerson {
  225.             /** Build Person object leaving optional fields set to default values */
  226.             public Person doBuild() {
  227.                 return mPerson;
  228.             }
  229.             /** Call any or none of these optional fields */
  230.             public GotOptional doOptional() {
  231.                 return new GotOptional();        
  232.             }
  233.         }
  234.        
  235.         //Since person is not immutable the only thing gained here is confidence that these were set according to persons whacky rules
  236.         class GotOptional {
  237.            
  238.             /** Build Person object */
  239.             public Person doBuild() {
  240.                 return mPerson;
  241.             }
  242.  
  243.             public GotOptionalAlternatives doOptionalAlternatives() {
  244.                 return new GotOptionalAlternatives();
  245.             }
  246.  
  247.             public GotOptional addClothing(String clothing) {
  248.                 mPerson.setClothing(clothing);
  249.                 return this;
  250.             }
  251.            
  252.             public GotOptional addTatoo(String tattoo) {
  253.                 mPerson.setTattoo(tattoo);
  254.                 return this;
  255.             }
  256.            
  257.             //Add any number of setters that have good default values and do not conflict with each other
  258.            
  259.         }
  260.        
  261.         //Ideally person wouldn't allow this anyway but person is set in stone so at least this provides a safer interface
  262.         public class GotOptionalAlternatives {
  263.  
  264.             /** Build Person object */
  265.             public Person doBuild() {            
  266.                 return mPerson;
  267.             }
  268.  
  269.             //Optional but conflicting setters. Might never be called.  Must never be called together.
  270.            
  271.  
  272.             public GotFavoriteBeer addFavoriteBeer(String favoriteBeer){
  273.                 //mFavoriteBeer = favoriteBeer;  //TODO remove
  274.                 mPerson.setFavoriteBeer(favoriteBeer); //GotFavoriteBeer
  275.  
  276.                 return new GotFavoriteBeer();
  277.             }
  278.            
  279.             public GotJobTitle addJobTitle(String jobTitle){
  280.                 //mJobTitle = jobTitle;  //TODO remove
  281.                 mPerson.setJobTitle(jobTitle); //GotJobTitle
  282.  
  283.                 return new GotJobTitle();
  284.             }
  285.         }
  286.        
  287.         //These are not strictly needed.  They are like one-statement {}'s after an 'if'.  Simply there if more gets added.
  288.  
  289.         public class GotFavoriteBeer {
  290.             /** Build Person object */
  291.             public Person doBuild() {            
  292.                 return mPerson;
  293.             }
  294.         }
  295.        
  296.         public class GotJobTitle {
  297.             /** Build Person object */
  298.             public Person doBuild() {            
  299.                 return mPerson;
  300.             }
  301.         }
  302.     }
RAW Paste Data