OO in JavaScript – A very different way – Firstly, you should have an object



OO in JavaScript – A very different way – Firstly, you should have an object

1 5


oo-in-javascript

OOP in JavaScript presentation

On Github abruzzi / oo-in-javascript

OO in JavaScript

A very different way

Created by Juntao Qiu / juntao.qiu, Bian Rui / psychebb

Firstly, you should have an object

首先, 你得有个对象

Brief history of oop

Software crisis

Software crisis

modularize

modularize

Class based OOP

Class based OOP

class Person {
	//attributes
	private String name;

	//methods
	public String getName();
	pubiic void setName(String name);
}
						

Class based OOP

Person juntao = new Person("Juntao");
Person rui = new Person("Rui");
						

Prototype based language

prototype Chain

Create An Object

var obj = new Object();
						

Or simply

var obj = {};
						

Object as Container

{
	name: "juntao",
	skills: ["JavaScript", "Ruby"]
}
						

Constructor

var LineItem = function(name, price, amount, unit) {
	this.name = name;
	this.price = price;
	this.amount = amount;
	this.unit = unit;	
}
						

Or

function LineItem(name, price, amount, unit) {
	this.name = name;
	this.price = price;
	this.amount = amount;
	this.unit = unit;
}
						

Methods

LineItem.prototype.totalPrice = function() {
	return this.price * this.amount;	
}

LineItem.prototype.format = function() {
	return "名称:" + this.name + 
	",数量:"+this.amount + this.unit + 
	",单价:"+this.price.toFixed(2)+"(元)"+
	",小计:"+ this.totalPrice()+"(元)";
}			
						

Create an Object

var apple = new LineItem("苹果", 15.00, 2, "市斤");

console.log(apple.totalPrice());
//30 

console.log(apple.format());
//名称:苹果,数量:2市斤,单价:15.00(元),小计:30(元)
						

Create another

var apple = new LineItem("苹果5s", 4680.00, 1, "台");

console.log(apple.totalPrice());
//4680

console.log(apple.format());
//名称:苹果5s,数量:1台,单价:4680.00(元),小计:4680(元)
						

It's all about reusable

Modeling

Modeling

var ShoppingCart = function() {
	this.collection = [];
}

ShoppingCart.prototype.add = function(item) {
	this.collection.push(item);
}

ShoppingCart.prototype.count = function() {
	return this.collection.length;
}
						

Modeling

var myCart = new ShoppingCart();
myCart.add(apple);
myCart.add(apple);
myCart.add(apple);

console.log(myCart.count());
//看什么看?没见过一次买三个苹果5s的吗?
						

Modeling

It's all about reality

Design by example

Observer pattern

Observer pattern - interface

function Observer() {
}

Observer.prototype.update = function() {
	throw new Error("not implemented");
}
						

Observer pattern - implementation

var bbs = Object.create(Observer.prototype);
bbs.update = function(data) {
	console.log(data);
}
						

Observer pattern - Subject

var Subject = function() {
	this.observers = [];
}

Subject.prototype.addObserver = function(observer) {
	this.observers.push(observer);
}

Subject.prototype.notify = function(data) {
	this.observers.forEach(function(observer) {
		observer.update(data);
	});
}	
						

Observer pattern - usage

var weather = new Subject();

weather.addObserver(bbs);

weather.notify("Cloudy in the morning");
						

Observer pattern - usage

var alwayson = Object.create(Observer.prototype);
alwayson.update = function(data) {
	alert(data);
}
						

Observer pattern - usage

var weather = new Subject();

weather.addObserver(bbs);
weather.addObserver(alwayson);

weather.notify("Cloudy in the morning");
						

high cohesion, loose coupling

Group realted stuff together

Separation of concerns

encapsulation

inheritance

polymorphism

solid

single responsbility

single responsbility

function displayPrice(sum) {
	console.log('总计:' + sum.toFixed(2) + '(元)')
}
							
function generateOutputPrice(sum) {
	return '总计:' + sum.toFixed(2) + '(元)'
}
function displayPrice(price) {
	console.log(price)
}
							

never be more than one reason for a class to change

open/closed

open/closed

function calculateArea(rectangles) {
	var area = 0;
	rectangles.forEach(function(rectangle) {
	    area += rectangle.width * rectangle.height;
	});
	return area;
}

var rectangles = [{
	width: 10,
	height: 20	
}, {
	width: 30,
	height: 20
}];

console.log(calculateArea(rectangles));
							

open/closed

var shapes = [{
	width: 10,
	height: 20	
}, {
	width: 30,
	height: 20
}, {
	radius: 10
}];
							

open/closed

function calculateArea(rectangles) {
	var area = 0;
	rectangles.forEach(function(rectangle) {
	    if(rectangle.radius) {
		        area += Math.PI * rectangle.radius * rectangle.radius;
	    } else {
		        area += rectangle.width * rectangle.height;
	    }
	});
	return area;
}
						

open/closed

var shapes = [{
	width: 10,
	height: 20	
}, {
	width: 30,
	height: 20
}, {
	radius: 10
}, {
	base: 20,
	height: 10
}];
						

open/closed

function Shape() {}

Shape.prototype.area = function() {
	throw new Error("not implemented");
}
						

open/closed

function Rectangle(width, height) {
	Shape.call(this);
	this.width = width;
	this.height = height;
}

Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.area = function() {
	return this.width * this.height;
}
						

open/closed

var rect1 = new Rectangle(10, 20);
var rect2 = new Rectangle(30, 20);
var shapes = [rect1, rect2];

function calculateArea(shapes) {
	var area = 0;
	shapes.forEach(function(shape) {
	    area += shape.area();
	});
	return area;
}
						

open/closed

function Circle(radius) {
	Shape.call(this);
	this.radius = radius;
}

Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.area = function() {
	return Math.PI * this.radius * this.radius;
}
						

open/closed

var rect1 = new Rectangle(10, 20);
var rect2 = new Rectangle(30, 20);
var circle1 = new Circle(10);
var shapes = [rect1, rect2, circle1];
						

liskov substitution

interface segregation

dependency inversion

Small functions

Separate units

different objects

THE END

https://github.com/abruzzi/oo-in-javascript