Solved

How do I pass arguments in a Builder design pattern ?

Posted on 2016-08-04
10
51 Views
Last Modified: 2016-08-09
Suppose I have user input values that I don't know ahead of time and I want to pass these values while creating the product.
Do I pass the values to the Director class or do I pass the values to the Builder class before passing the Builder object to the Director?

Possibility #1:

So, if I pass the values to the Director class, it would look like this:

             IProductBuilder myProduct = new ExpensiveProductBuilder();
            Director director = new Director();
            director.BuildProduct(myProduct, argument1, argument2);

Open in new window


Then in the Director class:

    class Director
    {
        public BuildProduct(IProductBuilder anyProduct, Base arg1, Top arg2)
        {
            anyProduct.BuildBase(arg1);
            anyProduct.BuildTop(arg2);         
        }
    }

Open in new window



Possibility #2

On the other hand, what if I pass the values to the Builder class before passing the Builder object to the Director?
So, if I pass the arguments into the Builder class it looks like this:

            IProductBuilder myProduct = new ExpensiveProductBuilder(argument1, argument2);
            Director director = new Director();
            director.BuildProduct(myProduct);

Open in new window



And then the Builder class would look like this:

    class ExpensiveProductBuilder
    {
        Product baseProduct = new Product();
        Base arg1;
        Top arg2;

        public ExpensiveProduct(Base arg1, Top arg2)
        {
            this.arg1 = arg1;
            this.arg2 = arg2;
        }

        public void BuildBase(arg1) { /* . . . */ }
        public void BuildTop(arg2) { /* . . . */ }
    }

Open in new window



Which of those two possibilities, if either, is the correct way or the usual way of passing arguments in a Builder pattern ?
If neither, then how is it done? Thanks.
0
Comment
Question by:XTO
  • 5
  • 5
10 Comments
 
LVL 32

Expert Comment

by:sarabande
ID: 41744036
Generally, a 'director' should not know about details. so you should not pass arguments to the director but to the product.

Director director = new Director();

if you always use a new director for each new product, you pretty well could do without a director as well or create it as an 'assistant' within the product class. also a 'product builder' class rarely has a  useful role. why not simply 'build' the product by using a 'create' or 'build' member function? or 'build it with the constructor:

IProduct myProduct = new ExpensiveProduct(argument1, argument2);

Open in new window


you already called it 'myProduct'. so what is the benefit of an additional 'Builder'.


if you would make the 'Director' a singleton then it could have a valuable role in order to manage 'all' products. or virtually create/build different products by using factory pattern.

Sara
0
 

Author Comment

by:XTO
ID: 41744290
"if you always use a new director for each new product"

I agree that creating the Director as a singleton is better.
I wasn't trying to imply that I would create a new director with each type of builder.

I would be using the same Director(which is what the Builder pattern calls for) for building a variety of products..

Director director = new Director(); // I can refactor this as a Singleton later.

IProductBuilder myProduct = new ExpensiveProductBuilder();
IProductBuilder yourProduct = new QualityProductBuilder();
IProductBuilder hisProduct = new CheapProductBuilder();
IProductBuilder herProduct = new ImportedProductBuilder();

director.BuildProduct(myProduct, argument1, argument2);
director.BuildProduct(yourProduct, argument3, argument4);
director.BuildProduct(hisProduct, argument5, argument6);
director.BuildProduct(herProduct, argument7, argument8);

Open in new window


". . . so what is the benefit of an additional 'Builder'."
The benefit of additional builders is to remove the complexity of building the product out of the product, especially when there are many possible variations of each.
It can also reduce the number of parameters to a constructor, and reduce the number of constructors.

"so you should not pass arguments to the director but to the product."
Do you mean, " . . . but to the Builder ?"
0
 
LVL 32

Expert Comment

by:sarabande
ID: 41745190
to remove the complexity of building the product out of the product

actually OOD means that objects act like real objects. if for example humans would have need a builder rather than grow themselves i doubt that we would be alive now.

i know there are a lot of bad samples like a string builder to build strings but you should know that most class libraries nowadays have a better design and provide complete objects which don't need helpers and builders.

Sara
0
 

Author Comment

by:XTO
ID: 41747271
Although the philosophy of OOD is very interesting to me and I enjoy thinking about it, and although I find the discussion of the subject to be fascinating, I started this thread to get an answer to an exact and specific question: "how do I pass arguments in a builder pattern?"

So, in a correct implementation of the Builder pattern, arguments should be sent to the Builder object; is that right? On the other hand, another possibility is that in a correct implementation of the Builder pattern, no arguments should be sent. In other words, if arguments need to be sent, then the Builder pattern can not be used as it does not allow for that.

The points on this thread go to the academically accurate answer to that question, with perhaps references to a well accepted GOF related specs paper, or a Martin Fowler article, or some Microsoft best practice document,  or an ACM article, or some similar industry standard consortium statement. Thanks.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 41747532
How do I pass arguments in a Builder design pattern ?
this was only the title of your question. in the body you described two possible concepts and asked

Which of those two possibilities, if either, is the correct way
'if either' obviously meant that that other designs were possible as well. if you changed your mind regarding this point you may consider to ask a new question where this is made clear already in the initial post.

generally, i don't think that builder and manager classes like the ones you have posted, are an appropriate design. they add complexity to the design concept which is not needed and violate OOD principles. why should you have a builder if you want to create a product? why should you use a manager to do the build if you all could do with the product class itself?

The points on this thread go to the academically accurate answer to that question
you should 'request for attention' (see button at your original question) and let the Moderators add some more topic areas and reschedule the question. currently it is only a little chance that other experts will participate and read the whole thread to end.

i don't think that there are published 'design patterns' of using product, builder, and manager classes. or if there are such articles, they probably would focus onto other points since 'design patterns' actually are more than the question which one of a bunch of related classes will get which arguments. they are concepts how a non-trivial functionality could be designed by using OOP design patterns. in almost all cases they are not specific for one programming language. for example the factory pattern describes how you virtually can create classes derived from the same baseclass. but the factory pattern will not determine whether you need an extra factory class or whether the common baseclass could handle the factory itself. of course if you ask for a c# design pattern, it is more likely that you also get a concrete sample implementation, but this not the pattern.

from an OOP Point of view, you always would try to avoid redundancy and encapsulate member data into the classes which owns them. following the last point you would have code like

IProductBuilder myProductBuilder = new ExpensiveProductBuilder();
Director director = new Director();
MyProduct myProduct = director.BuildProduct(myProductBuilder);
myProduct.SetArguments(arg1, arg2);

Open in new window



what is only slightly different to your first possibility but avoids redundancy when passing the arguments. it also shows the redundancy of the builder and the manager as long as they don't get a reasonable role in this scenario.

note, if the arguments are not properties of the product but tell the builder how to build the product, it would make much more sense to have a builder. and of course you would pass the arguments to the builder and not to the manager in this case.

Sara
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:XTO
ID: 41747578
. . .  if the arguments . . . tell the builder how to build the product, . . . you would pass the arguments to the builder . . . .

Based on that statement, then possibility #2 from the original question fits that rule:

IProductBuilder myProduct = new ExpensiveProductBuilder(argument1, argument2);

Open in new window

Please confirm if that is correct. If so, then I will award full points and close the question. Thanks.
0
 
LVL 32

Accepted Solution

by:
sarabande earned 500 total points
ID: 41747621
Please confirm if that is correct. If so, then I will award full points and close the question. Thanks.
you don't have to give points if you think your question is not answered. you can accept one of your own comments (0 Points). or only give assist points.

 
Please confirm if that is correct.

yes. if your builder creates different product objects depending on the arguments, then it follows the factory pattern, and the builder is some kind of a factory class.

but actually in the factory pattern you would have a singleton factory and you wouldn't use different builder classes but only different product classes. so i still think your design has redundancies since a good implemention of a factory pattern would allow code like,

MyExpensiveProduct myProduct = theProductBuilder("expensive",  arguments);

Open in new window


where theProductBuilder is the "factory" and passes as well builder argument(s) and arguments for the product, for example a variable length argument list which is individual for the created product class (type).

Sara
0
 

Author Comment

by:XTO
ID: 41747737
I will award full points for the information that possibility #2 is the better option. References are not necessary, but merely "preferred."
Thanks for the additional information on the factory pattern. That is also interesting to me.
Now that the original question has been answered, I can comment on some of the philosophical and open-ended statements.

actually OOD means that objects act like real objects. if for example humans would have need a builder rather than grow themselves i doubt that we would be alive now.

Expanding from the premise that software objects should emulate actual objects, most things do not build themselves. automobiles, phones, pharmaceuticals, homes, clothes, etc, are indeed assembled. Both the assembled product and the thing that assembles it are objects. In other words, the builder is also  an object in the real world.

Even for people, when they are conceptually abstracted for software, their real world context does "build" the instance of that abstraction. For example, in the real world context of a company, an employee person needs to have the company assign them a role (manager, consultant, sales), then assign them a department, a geographic region, etc, and then based on those assignments (properties), figure out and calculate other details for the employee such as calculating salary, vacation time, network security rights, building access permissions, etc.
A software that emulates and automates that would need the properties sent to the object that builds.
In such a case, it would be handy to have a "manager builder" that accepts other properties, and then both assigns those properties, and then also calculates the other variables.
People who are abstracted for software in universities, militaries, social programs, etc, can be similarly addressed (no pun intended).

Even in the case of an actual biological human where the building mechanism is internal in the real world, there is still an internally distinct set of mechanisms for processing DNA data and building the tissue and organs which follow. If we were building a human genome modeling software, for instance, the class abstraction in the virtual software realm could contain a class for receiving DNA sequence arguments, converting that to genetic information, and then building various organs or tissue: heart, liver, bone.
0
 

Author Closing Comment

by:XTO
ID: 41747740
I got the answer to my question and some other helpful suggestions upon which I can follow up on later.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 41748402
most things do not build themselves
probably the word 'build' is the cause for the misunderstanding of what i said. if we build a software object we normally are not describing a life-cycle or a growing process but create an already complete object. if you don't add the known properties and member data directly to the object when creating it, but use a 'builder' you always should ask why the creator (caller) needs to know of the existence of a builder at all and have to create two objects instead of one. in other words, if an object needs an assistent or builder,  this should be an internal matter of the object but nothing what the 'users' need to consider.

assume your objects are persistent and have their information stored in a database. obviously you would not create an SQL environtment handler, an SQL Database handler, an SQL statement builder, an SQL reader, an SQL translator at every place where you want to create an object that gets its data from the database. same applies if you want to store memory objects. but it is also clear that all these helpers were needed when creating objects which already were persistent.

MyPersistentProduct p = new MyPersistentProduct(productNumber);
p.LoadPersistentData();

Open in new window


a good design always will try to encapsulate the knowledge how something was implemented away from the users of the objects to the objects themselves. that way you easily could change the methods to retrieve data. in the above sample, you might want to get the product data from a Server instead from the database, what you easily can handle in the LoadPersistentData() function. note, LoadPersistentData could be a baseclass member function, or could use a builder or manager, whatever.

Sara
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Introduction This article explores the design of a cache system that can improve the performance of a web site or web application.  The assumption is that the web site has many more “read” operations than “write” operations (this is commonly the ca…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now