design-patterns-api

0.0.15 • Public • Published

design-patterns-api

Implementation of Design Patterns as Interface classes.

These are early releases (until 1.0.0 version). More to come shortly as I will use this package for my own projects anyway [|8^)>

Only a subset of the Design Patterns are released ATM

There are many online documents about Design Patterns. An important part of this project was to mine them and propose for each pattern the 'least worst' design (from my perspective). My proposals should just be considered as an ongoing work (for which your feedback is welcome) and certainly not a reference. Thus I advise you to check and evaluate by yourself these documents (I have gathered them in References paragraph) to check it they fits your learning curve and design issues.

Changelog for Release 0.0.15 :

  • BugFixes and better code reuse in Custom Loggers due to refactoring of mixin-interface

Available Patterns

Naming conventions: for any given interface class, its name is written with PascalCase convention (e.g. IAbstractFactory) and its source code uses snake_case convention (e.g. i_abstract_factory.js)

Why ...args ? Thanks to the rest parameter feature of javascript es6 (...args), most interface services accept optional and variable number of arguments.

Why all these xxx_id arguments ? This is a design choice motivated by 2 design intents. The first design intent is when the service call is delegated or propagated (e.g. 'request_id' argument is propagated in Adapter when IAdapter.request() calls IAdaptee.specificRequest()). The second design intent is to avoid unnecessary class proliferation by using this xxx_id argument as a way to make the call more specific (e.g. 'request_id' argument when calling IHandler.handleRequest() of Chain Of Responsability)

Creational

  • Abstract Factory (changed): IAbstractFactory, IProduct
  • Factory Method: ICreator, IProduct
  • Builder: IBuilder, IProduct

Behavioral

  • Observer: IObserver and ISubject
  • Iterator (changed): IIterator, ICollection
  • State (changed): IState, IStateContext
  • Chain of Responsability: IHandler, IContext
  • Visitor: IVisitor, IElement
  • Memento: IMemento, IOriginator, ICareTaker
  • Strategy (new): IStrategy, IStrategyContext

Structural

  • Bridge: IImplementor
  • Adapter: IAdapter, IAdaptee
  • Facade: IFacade

How to implement a Design Pattern

A given Design Pattern is composed of one or more participants, this is very much like Role(s) in a play. Within design-patterns-api project, each participant is implemented as an interface classs. Thus, in order to implement a Design Pattern you must implement the interface class(es). Please refer to How to code an Implementation class in the documentation of mixin-interface package.

Code Sample: LoggerFactory

LoggerFactory shows how to delegate the instanciation of a Logger (a more flexible way to log traces than console.log) by implementing the Abstract Factory design pattern.

See source code in: ./src/implementation_samples/creational. It is demonstrated in ./test.js Unit Test. There are 4 files in this code sample (logger_factory.js, arrow_prefix_logger.js, timestamp_prefix_logger.js and count_prefix_logger.js), and the client code which uses them is in ./test.js (Unit Test).

Installation and Usage:

npm install design-patterns-api -S

How to run the Unit Test

Step 1: Install Prerequisite Tools

Install NodeJS and Git

Step 2: Clone the 'design-patterns-api' repository locally

Open a command shell then enter the following commands:

git clone git://github.com/Echopraxium/design-patterns-api
cd design-patterns-api
npm update

Step 3: Run the Unit Test

Now enter the following command:

node test.js

You should get the following output:

=================================================================
========== Unit Test for 'design-patterns-api' package ==========
=================================================================
1. Creational Patterns
----------
1.1. Abstract Factory
'IAbstractFactory'          is an interface ? true
Demonstrate 'Abstract Factory' Design pattern by changing DefaultLogger:

==> Logger is now 'arrow_prefix_logger_0'

[14:50:06 PM] Logger is now 'timestamp_prefix_logger_0'

[0] Logger is now 'count_prefix_logger_0'

----------
1.2. Factory Method
'ICreator'                  is an interface ? true
'IProduct'                  is an interface ? true
----------
1.3. Builder
'IBuilder'                  is an interface ? true
----------------------------------------
2. Behavioral Patterns
----------
2.1. Observer
'IObserver'                 is an interface ? true
'ISubject'                  is an interface ? true
----------
2.2. Iterator
'IIterator'                 is an interface ? true
'ICollection'               is an interface ? true
----------
2.3. State
'IState'                    is an interface ? true
'IStateContext'             is an interface ? true
----------
2.4. Chain Of Responsability
'IHandler'                  is an interface ? true
'IRequest'                  is an interface ? true
----------
2.5. Visitor
'IVisitor'                  is an interface ? true
'IElement'                  is an interface ? true
----------
2.6. Memento
'IMemento'                  is an interface ? true
'IOriginator'               is an interface ? true
'ICareTaker'                is an interface ? true
----------
2.7. Strategy
'IStrategy'                 is an interface ? true
'IStrategyContext'          is an interface ? true
----------------------------------------
3. Structural Patterns
----------
3.1. Bridge
'IImplementor'              is an interface ? true
----------
3.2. Adapter
'IAdapter'                  is an interface ? true
'IAdaptee'                  is an interface ? true
==================== End of Unit Test ====================

References

Package Sidebar

Install

npm i design-patterns-api@0.0.15

Version

0.0.15

License

MIT

Last publish

Collaborators

  • echopraxium