Builder design pattern

by John Wick

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js"></script>
<div class="advert">

</div>

CSS

.advert {
  background: white;
  border:1px solid red;
  width: 300px;
  height: 300px;
}

.circle{
  width:10px;
  height:10px;
  border-radius:50px;
  text-align:center;
  background:#000;
  position:absolute;
}

JavaScript

// Builder design pattern
(function(win, $) {
  function Circle() {
    this.item = $('<div class="circle"></div>');  
  };

  Circle.prototype.color = function(clr) {
    this.item.css('background', clr);
  };
  
  Circle.prototype.move = function(left, top) {
    this.item.css('left', left);
    this.item.css('top', top);
  };

  Circle.prototype.get = function() {
    return this.item;
  };
  
  function RedCircleBuilder() {
    this.item = new Circle();    
    this.init();
  };

  RedCircleBuilder.prototype.init = function() {
    //nothing
    // this.item.color("red"); 
  };
  RedCircleBuilder.prototype.get = function() {
    return this.item;
  };  

  function BlueCircleBuilder() {
    this.item = new Circle();
    this.init();
  };

  BlueCircleBuilder.prototype.init = function() {
    this.item.color("blue"); 
  };

  BlueCircleBuilder.prototype.get = function() {
    return this.item;
  };  
  
  CircleFactory = function() {
    this.types = {};
    this.create = function(type) {
      return new this.types[type]().get();
    }

    this.register = function(type, cls) {
      if(cls.prototype.init && cls.prototype.get) {
        this.types[type] = cls;
      }
    }
  };
  
  var CircleGeneratorSingleton = (function() {
    var instance;

    function init() {
      var _aCircle = [],
          _stage = $('.advert'),
          _cf = new CircleFactory();
          _cf.register('red', RedCircleBuilder);
          _cf.register('blue', BlueCircleBuilder);

      function _position(circle, left, top) {
        circle.move(left, top);
      }

      function create(left, top, type) {
        var circle = _cf.create(type);
        circle.move(left, top);
        return circle;
      }

      function add(circle) {
        _stage.append(circle.get());
        _aCircle.push(circle);
      }

      function index() {
        return _aCircle.length;
      }

      // using Revealing pattern
      return {
        index: index,
        create: create,
       ...