- Mastering JavaScript Design Patterns
- Simon Timms
- 614字
- 2021-08-05 17:14:59
Builder
In our fictional world, we sometimes have some rather complicated classes that need to be constructed. The classes contain different implementations of an interface depending on how they are constructed. In order to simplify the building of these classes and encapsulate the knowledge of building the class away from the consumers, a builder may be used. Multiple concrete builders reduce the complexity of the constructor in the implementation. When new builders are required, a constructor does not need to be added, a new builder just needs to be plugged in.
Tournaments are an example of a complicated class. Each tournament has a complicated setup involving the events, the attendees, and the prizes. Much of the setup for these tournaments is similar: each one has a joust, archery, and a melee. Creating a tournament from multiple places in the code means that the responsibility of knowing how to construct a tournament is distributed. If there is a need to change the initiation code, then it must be done in a lot of different places.
Employing a Builder pattern avoids this issue by centralizing the logic necessary to build the object. Different concrete builders can be plugged into the builder to construct different complicated objects, as shown in the following diagram:

Implementation
Let's drop in and look at some of the code. To start with, we'll create a number of utility classes, which will represent the parts of a tournament. We can see this in the following code:
var Event = (function () { function Event(name) { this.name = name; } return Event; })(); Westeros.Event = Event; var Prize = (function () { function Prize(name) { this.name = name; } return Prize; })(); Westeros.Prize = Prize; var Attendee = (function () { function Attendee(name) { this.name = name; } return Attendee; })(); Westeros.Attendee = Attendee;
The tournament itself is a very simple class as we don't need to assign any of the public properties explicitly, as shown in the following code:
var Tournament = (function () { this.Events = []; function Tournament() { } return Tournament; })(); Westeros.Tournament = Tournament;
We'll implement two builders that create different tournaments. This can be seen in the following code:
var LannisterTournamentBuilder = (function () { function LannisterTournamentBuilder() { } LannisterTournamentBuilder.prototype.build = function () { var tournament = new Tournament(); tournament.events.push(new Event("Joust")); tournament.events.push(new Event("Melee")); tournament.attendees.push(new Attendee("Jamie")); tournament.prizes.push(new Prize("Gold")); tournament.prizes.push(new Prize("More Gold")); return tournament; }; return LannisterTournamentBuilder; })(); Westeros.LannisterTournamentBuilder = LannisterTournamentBuilder; var BaratheonTournamentBuilder = (function () { function BaratheonTournamentBuilder() { } BaratheonTournamentBuilder.prototype.build = function () { var tournament = new Tournament(); tournament.events.push(new Event("Joust")); tournament.events.push(new Event("Melee")); tournament.attendees.push(new Attendee("Stannis")); tournament.attendees.push(new Attendee("Robert")); return tournament; }; return BaratheonTournamentBuilder; })(); Westeros.BaratheonTournamentBuilder = BaratheonTournamentBuilder;
Finally, the director, or as we're calling it TournamentBuilder
, simply takes a builder and executes it:
var TournamentBuilder = (function () { function TournamentBuilder() { } TournamentBuilder.prototype.build = function (builder) { return builder.build(); }; return TournamentBuilder; })(); Westeros.TournamentBuilder = TournamentBuilder;
Again, you'll see that the JavaScript implementation is far simpler than the traditional implementation as there is no need for interfaces.
Builders need not return a fully realized object. This means that you can create a builder that partially hydrates an object, then allows the object to be passed onto another builder for it to finish. This approach allows us to divide the work of building an object amongst several classes with limited responsibility. In our preceding example, we could have a builder that is responsible for populating the events and another that is responsible for populating the attendees.
Does the builder pattern still make sense in view of JavaScript's prototype extension model? I believe so. There are still cases where a complicated object needs to be created according to different approaches.
- 計算機網(wǎng)絡(luò)
- Visual FoxPro程序設(shè)計教程(第3版)
- Designing Hyper-V Solutions
- 區(qū)塊鏈:以太坊DApp開發(fā)實戰(zhàn)
- Microsoft System Center Orchestrator 2012 R2 Essentials
- Python漫游數(shù)學(xué)王國:高等數(shù)學(xué)、線性代數(shù)、數(shù)理統(tǒng)計及運籌學(xué)
- C語言課程設(shè)計
- Service Mesh實戰(zhàn):基于Linkerd和Kubernetes的微服務(wù)實踐
- 匯編語言編程基礎(chǔ):基于LoongArch
- Drupal 8 Development Cookbook(Second Edition)
- Mastering Bootstrap 4
- LabVIEW入門與實戰(zhàn)開發(fā)100例(第4版)
- Apache Solr for Indexing Data
- 跟小樓老師學(xué)用Axure RP 9:玩轉(zhuǎn)產(chǎn)品原型設(shè)計
- Mastering VMware vSphere Storage