For help call US Flag +44 75405 52750 or Email Us

Creational patterns

Development

In this article we will cover creational patterns in javascript. We will also write typescript of those javascript patterns and have a look at those test for typescript code.

 

Prerequisites:

  • Basic knowledge of javascript
  • Basic knowledge of typescript
  • Knowledge of test in typescript
  • Environment setup for typescript code and its tests

 

This article will teach you how to write creational patterns in typescript and test them.

 

What is typescript?

 

Typescript is a superset of javascript that compiles to plain javascript. It is developed by microsoft.

 

To learn more about typescript, you can check its documentation. You can also watch tutorial series from this youtube playlist.

 

What are tests?

 

According to wikipedia its definition is as follows:

 

Test techniques include the process of executing a program or application with the intent of finding software bugs (errors or other defects), and verifying that the software product is fit for use.

 

So tests make life of a programmer easy. On first look it seems a tedious and a time consuming process but as a long term process, tests makes programming fast and easy.

 

What is creational patterns?

 

Ensuring that classes have minimal dependence on other classes is the key

to building a system that can change fluently with the changing needs of those using

the software.

 

Allowing classes closely related can make a huge impact on code. Once its set you can’t change it easily. You have to change all the places inside code to make it work.

Here’s where creational patterns comes into role, they try to improve degree of coupling in applications and increase the opportunities for code reuse.

 

Creational patterns are as follows:

  • Abstract factory
  • Builder
  • Factory method
  • Singleton
  • Prototype

 

Actual coding…

 

Lots of talking now let’s dive directly into the creational patterns in javascript.

 

Note:- as for the convention in this article, we will first write javascript code, then see its typescript version and finally i will show how to write test for that code.

 

Abstract factory

 

Let’s take the example of an Ice Cream Factory, there were two partners(Wonka and John) of this factory. And both were not good friends, so both always tried to get management of factory under their control. One partner was peaceful while other was on iron fist. This factory was too big to handle by an individual. So each partner had their own secretary and advisors.

 

Now the problem is that, the change in partners frequently makes our application brittle. As one manages factory quietly and other in rush. So it’s very necessary to take care of. Brittle applications do not fare well in an ever-changing world.

 

Below figure shows the structure of classes inside this situation:

Now one solution to this is Abstract Factory pattern. Here each interface (Team, Partner, Secretary) defines their respective classes and CEO is a main abstract factory:

Each abstract factory may have one or more implementations for each of partner. These are know as concrete factories and each will implement interface provided by the abstract factory. These concrete classes are known as products.

 

But what about code for interface?

 

This is exactly the problem, the lack of classes in javascript precludes the need for interfaces to describe classes. Instead of having interfaces, we’ll move directly to creating the classes as shown below:

So, the solution is not so effective. Instead of using interface, javascript depends upon us to provide all appropriate methods. The interpreter simply assumes that if your class implements the method, then it is that class. This is known as duck typing.

 

This was the concept of Abstract Factory, now let’s look at how to code it into javascript.

 

Code:

 

Let’s first see how we can actually implement partner class. Following code creates a partner class:

 

var Wonka = (function(){

function Wonka(){

}

Wonka.prototype.manage(){

};

Wonka.prototype.sell(){

};

return Wonka;

})();

 

This is regular concrete class and contains implementation details. We will also see the implementation of secretary class as below:

 

var Wonka_PA = (function(){

function Wonka_PA(){

}

Wonka_PA.prototype.help(){

};

return Wonka_PA;

})();

 

Implementation of concrete factory is like this:

 

var quiet_factory = (function(){

function quiet_factory(){

}

quiet_factory.prototype.get_partner(){

return new Wonka();

};

quite_factory.prototype.get_secretary(){

return new Wonka_PA();

};

return quite_factory();

})();

 

Similarly, implementation for other partner will be:

 

var rush_factory = (function(){

function rush_factory(){

}

rush_factory.prototype.get_partner(){

return new Johny();

};

rush_factory.prototype.get_secretary(){

return new Johny_PA();

};

return rush_factory();

})();

 

To use Abstract Factory pattern, we’ll have to make a class that requires the use of one partner. Its implementation is as below:

 

var boardMeeting = (function(){

function boardMeeting(abstractFactory){

this.abstractFactory = abstractFactory;

this.maxMistake = 3;

}

boardMeeting.prototype.mistake = function(mistake){

if(mistake.severity < this.maxMistake){

this.abstractFactory.get_secretary().help();

}else{

this.abstractFactory.get_partner().manage();

}

};

return boardMeeting;

})();

 

We can call this boardMeeting class and inject different functionality depending upon the factory we pass.

 

var boardMeeting1 = new boardMeeting(new quiet_factory());

boardMeeting1.mistake({severity: 2});

boardMeeting1.mistake({severity: 4});

 

var boardMeeting2 = new boardMeeting(new rush_factory());

boardMeeting2.mistake({severity: 2});

boardMeeting2.mistake({severity: 4});

 

It may be a useful pattern when attempting to ensure that a set of objects be used together without substitutions.

Typescript:

 

Now, with typescript we have some advantages of OOP. So, here we can use interface, classes and many other things. Here, we will be making two teams and generate an abstract factory which selects one of the team.  Without talking too much let’s see how code looks like in typescript:

 

interface Team{

partner: Partner;

secretary: Secretary;

}

 

interface Partner{

management_rate: number;

}

 

Interface Secretary{

help_rate: number;

}

 

Here, we created three interfaces. Now we will create an interface for the concrete factory.

 

interface boardMeeting{

get_team(): Team;

get_partner(): Partner;

get_secretary(): Secretary;

}

 

Now, we will simply create a CEO class as our abstract factory.

 

class CEO{

select_team(decision: boardMeeting): Test{

let team = decision.get_team();

team.partner = decision.get_partner();

team.secretary = decision.get_secretary();

return team;

}

}

 

What we will do now is, implement these interfaces for our teams.

 

class Wonka implements Partner {

management_rate: number;

}

 

class Wonka_PA implements Secretary {

help_rate: number;

}

 

class Wonka_T implements Team {

partner: Wonka;

secretary: Wonka_PA;

}

 

class quiet_factory implements boardMeeting{

get_team(): Wonka_T {

return new Wonka_T();

}

get_partner(): Wonka {

return new Wonka();

}

get_secretary(): Wonka_PA {

return new Wonka_PA();

}

}

 

Similarly, we will have same code for other team Johny_T. Now, we will try using these with our abstract factory class.

 

let CEO = new CEO();

 

let quiet_factory = new quiet_factory();

let rush_factory = new rush_factory();

 

let Wonka_T = CEO.select_team(quiet_factory);

let Johny_T = CEO.select_team(rush_factory);

 

This was the implementation of our Ice Cream Factory into typescript code.

 

Tests:

 

Now, we would like to write tests for our abstract factory class. We will be using jasmine to test our typescript abstract factory.

 

describe(‘abstract factory’, () => {

 

it(‘should check presence of objects’, () => {

expect(CEO).toBe(true);

});

it(‘should check presence of concrete factory objects’, () => {

expect(quiet_factory).toBe(true);

expect(rush_factory).toBe(true);

});

it(‘should check the presence of Team objects’, () => {

expect(Wonka_T).toBe(true);

expect(Johny_T).toBe(true);

});

it(‘should check if partner and secretary of teams are defined’, () => {

expect(Wonka_T.partner).toBeDefined(true);

expect(Wonka_T.secretary).toBeDefined(true);

expect(Johny_T.partner).toBeDefined(true);

expect(Johny_T.secretary).toBeDefined(true);

});

 

});

 

This test checks for the availability of objects created by our abstract factory.

Builder

 

Now, both the teams of Wonka and Johny organizes different tournaments at ice cream factory in order to get attention. Tournaments are very complex to create in codes. They contain events, prizes, and attendees, but it becomes very easy when it is to be created separately. So what we will do is create a concrete builder which builds these tournaments for each team and then we will make a builder which creates this concrete builder.

 

The main aim of the builder is to hide the implementation of a concrete builder from the user. We just need to pass that concrete builder and it will automatically create it for us.

Implementation

 

First, we will implement event, prize and attendee classes.

 

var Event = (function () {

function Event(name) {

this.name = name;

}

return Event;

})();

Wonka.Event = Event;

var Prize = (function () {

function Prize(name) {

this.name = name;

}

return Prize;

})();

Wonka.Prize = Prize;

var Attendee = (function () {

function Attendee(name) {

this.name = name;

}

return Attendee;

})();

Wonka.Attendee = Attendee;

 

Now, the tournament class is very simple.

 

var Tournament = (function () {

this.Events = [];

function Tournament() {

}

return Tournament;

})();

Wonka.Tournament = Tournament;

 

We will further create two concrete builders which will create tournaments as follows:

 

var WonkaTournamentBuilder = (function(){

function WonkaTournamentBuilder() {

}

WonkaTournamentBuilder.prototype.build = function(){

var tournament = new Tournament();

tournament.events.push(new Event(“Eaters”));

tournament.attendee.push(new Attendee(“Jimmie”));

tournament.prizes.push(new Prize(“Gold”));

return tournament;

};

return WonkaTournamentBuilder;

})();

 

Factory.WonkaTournamentBuilder = WonkaTournamentBuilder;

 

var JohnyTournamentBuilder = (function(){

function JohnyTournamentBuilder() {

}

WonkaTournamentBuilder.prototype.build = function(){

var tournament = new Tournament();

tournament.events.push(new Event(“Makers”));

tournament.attendee.push(new Attendee(“Louis”));

tournament.prizes.push(new Prize(“Gold”));

return tournament;

};

return JohnyTournamentBuilder;

})();

 

Factory.JohnyTournamentBuilder = JohnyTournamentBuilder;

 

After that the TournamentBuilder simply takes a builder and executes it,

 

var TournamentBuilder = (function () {

function TournamentBuilder() {

}

TournamentBuilder.prototype.build = function (builder) {

return builder.build();

};

return TournamentBuilder;

})();

Factory.TournamentBuilder = TournamentBuilder;

 

This implementation in javascript is relatively easier than any other OOP language. As it has no use of interface it makes all this really easy to implement.

 

Typescript:

 

We first create an interface for our Tournament class.

 

interface Tournament{

events: Event;

prizes: Prize;

attendees: Attendee;

}

 

class WonkaTournamentBuilder implements Tournament {

constructor(){

this.events.push(“Eaters”);

this.attendees.push(“Jimmie”);

this.prizes.push(“Gold”);

}

}

 

class JohnyTournamentBuilder implements Tournament {

constructor(){

this.events.push(“Makers”);

this.attendees.push(“Louis”);

this.prizes.push(“Gold”);

}

}

 

class TournamentBuilder {

constructor(builder: Tournament){

builder.build();

}

}

 

Test:

 

describe(‘Builder’, () => {

it(‘should create two classes’, () => {

expect(WonkaTournamentBuilder).toBe(true);

expect(JohnyTournamentBuilder).toBe(true);

});

});

Post a comment