Core JavaScript

Builder Design Pattern

This Javascript program demonstrates a builder design pattern.

Builder.html

<!DOCTYPE html>
<html>
	<head>
		<title>XoaX.net's Javascript</title>
		<script type="text/javascript" src="Builder.js"></script>
		<style type="text/css">
			.cDrawing {
				background-color: #F0F0F0;
				border:1px solid #444444;
			}
		</style>
	</head>
	<body onload="Initialize()">
		<canvas id="idCanvas" class="cDrawing" width="400" height ="480"></canvas>
		<svg id="idSvg" class="cDrawing" width="400px" height="480px"
			xmlns="http://www.w3.org/2000/svg" viewBox="0.0 0.0 400 480"></svg>
	</body>
</html>

Builder.js

function Initialize() {
	let qCanvasElement = document.getElementById("idCanvas");
	let qContext = qCanvasElement.getContext("2d");
	let qSvgElement = document.getElementById("idSvg");

	let qCanvasBuilder = new CCanvasBuilder(qContext);
	let qSvgBuilder = new CSvgBuilder(qSvgElement);

	let qDirector1 = new CDirector(qCanvasBuilder);
	qDirector1.DrawMan();
	let qDirector2 = new CDirector(qSvgBuilder);
	qDirector2.DrawMan();
}

class CDirector {
	#mqBuilder;
	constructor(qBuilder) {
		this.#mqBuilder = qBuilder;
	}
	DrawMan() {
		this.#mqBuilder.DrawCircle(200, 100, 50);
		this.#mqBuilder.DrawLine(200, 150, 200, 300);
		this.#mqBuilder.DrawLine(100, 200, 300, 200);
		this.#mqBuilder.DrawLine(200, 300, 150, 400);
		this.#mqBuilder.DrawLine(200, 300, 250, 400);
	}
}

class CABuilder {
	constructor() {
		// This can be used to detect instantiation of the abstract class.
		if (this.constructor === CABuilder) {
			throw new Error("Instantiated abstract class error: CABuilder");
		}
	}
	DrawCircle(x, y, r) {
		throw new Error("Abstract method DrawCircle() must be implemented!");
	}
	DrawLine(x1, y1, x2, y2) {
		throw new Error("Abstract method DrawLine() must be implemented!");
	}
}

class CCanvasBuilder extends CABuilder {
	#mqContext2D;
	constructor(qCanvasContext2D) {
		super();
		this.#mqContext2D = qCanvasContext2D;
	}
	DrawCircle(x, y, r){
		const dCx = x;
		const dCy = y;
		const dRadius = r;
		const dArcStart = 0.0;
		const dArcEnd =  2.0*Math.PI;
		const bCounterClockwise = true;
		this.#mqContext2D.strokeStyle = "black";
		this.#mqContext2D.lineWidth = 1;
		this.#mqContext2D.beginPath();
		this.#mqContext2D.arc(dCx, dCy, dRadius, dArcStart, dArcEnd, bCounterClockwise);
		this.#mqContext2D.stroke();
	}
	DrawLine(x1, y1, x2, y2) {
		this.#mqContext2D.strokeStyle = "black";
		this.#mqContext2D.lineWidth = 1;
		this.#mqContext2D.beginPath();
		this.#mqContext2D.moveTo(x1, y1);
		this.#mqContext2D.lineTo(x2, y2);
		this.#mqContext2D.stroke();
	}
}

class CSvgBuilder extends CABuilder {
	#mqSvgElement;
	constructor(qSvgElement) {
		super();
		this.#mqSvgElement = qSvgElement;
	}
	DrawCircle(x, y, r){
		let qCircle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
		qCircle.setAttribute('cx', x);
		qCircle.setAttribute('cy', y);
		qCircle.setAttribute('r', r);
		qCircle.setAttribute('fill', 'none');
		qCircle.setAttribute('stroke-width', '1');
		qCircle.setAttribute('stroke', 'rgb(0, 0, 0)');
		this.#mqSvgElement.appendChild(qCircle);
	}
	DrawLine(x1, y1, x2, y2) {
		let qLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
		qLine.setAttribute('x1', x1);
		qLine.setAttribute('y1', y1);
		qLine.setAttribute('x2', x2);
		qLine.setAttribute('y2', y2);
		qLine.setAttribute('stroke-width', '1');
		qLine.setAttribute('stroke', 'rgb(0, 0, 0)');
		this.#mqSvgElement.appendChild(qLine);
	}
}
 

Output

 
 

© 2007–2026 XoaX.net LLC. All rights reserved.