建造者模式(Builder)
將一個(gè)復(fù)雜對(duì)象的構(gòu)建層與其表示層相互分離,同樣的構(gòu)建過(guò)程可采用不同的表示
特點(diǎn)
前面的工廠模式主要是為了創(chuàng)建對(duì)象實(shí)例或者類簇(抽象工廠),關(guān)心的是最終產(chǎn)出(創(chuàng)建)的是什么。不關(guān)心你創(chuàng)建的整個(gè)過(guò)程,僅僅需要知道你最終創(chuàng)建的結(jié)果。所以通過(guò)工廠模式我們得到的都是對(duì)象實(shí)例或者類簇。
然而建造者模式更復(fù)雜一些,其目的也是創(chuàng)建對(duì)象,但是更多關(guān)心的是創(chuàng)建這個(gè)對(duì)象的整個(gè)過(guò)程,甚至創(chuàng)建對(duì)象的每一個(gè)細(xì)節(jié)
案例需求
有一些想找工作的人,想借助咱們公司的網(wǎng)站發(fā)布自己的簡(jiǎn)歷,咱們公司將他們的簡(jiǎn)歷向外推銷。要求除了將他們的興趣以及一些特長(zhǎng)發(fā)布在頁(yè)面里,其他信息,比如聯(lián)系方式,不要發(fā)布在網(wǎng)站上。要讓需求公司來(lái)找咱們。他們想找的工作可以分類,比如對(duì)于喜歡編程的人來(lái)說(shuō)他們要找的職位就是工程師(engineer)了,這里可能還有一些描述等。
實(shí)現(xiàn)
我們需要的不僅僅是應(yīng)聘者一個(gè)實(shí)例,還要在創(chuàng)建過(guò)程中注意一下這位應(yīng)聘者都有哪些興趣愛好、他的姓名等信息,他所期望的職位是什么,等等。這些關(guān)注點(diǎn)都是需要我們創(chuàng)建的。
//創(chuàng)建一個(gè)人類
var Human = function (param) {
//技能
this.skill = param && param.skill || '保密';
//興趣愛好
this.hobby = param && param.hobby || '保密';
}
//人類原型方法
Human.prototype = {
getSkill: function () {
return this.skill;
},
getHobby: function () {
return this.hobby;
}
}
//實(shí)例化姓名類
var Named = function (name) {
var that = this;
//構(gòu)造器
//構(gòu)造函數(shù)解析姓名的姓與名
(function (name, that) {
that.wholeName = name;
if (name.indexOf(' ') > -1) {
that.FirstName = name.slice(0, name.indexOf(' '));
that.secondName = name.slice(name.indexOf(' '));
}
})(name, that);
}
//實(shí)例化職位類
var Work = function (work) {
var that = this;
//構(gòu)造器
//構(gòu)造函數(shù)中通過(guò)傳入的職位特征來(lái)設(shè)置相應(yīng)職位以及描述
(function (work, that) {
switch (work) {
case 'code':
that.work = '工程師';
that.workDescript = '每天沉醉于編程';
break;
case 'UI':
case 'UE':
that.work = '設(shè)計(jì)師';
that.workDescript = '設(shè)計(jì)更似一種藝術(shù)';
break;
case 'teach':
that.work = '教師';
that.workDescript = '分享也是一種快樂(lè)';
break;
default:
that.work = work;
that.workDescript = '對(duì)不起,我們還不清楚您所選職位的相關(guān)描述';
}
})(work, that)
}
//更換期望的職位
Work.prototype.changeWork = function (work) {
this.work = work;
}
//添加對(duì)職位的描述
Work.prototype.changeDescript = function (sentence) {
this.workDescript = sentence;
}
/**
* 應(yīng)聘者建造者
* @param {*} name 姓名
* @param {*} work 期望職位
*/
var Person = function (name, work) {
//創(chuàng)建應(yīng)聘者緩存對(duì)象
var _person = new Human();
//創(chuàng)建應(yīng)聘者姓名解析對(duì)象
_person.name = new Named(name);
//創(chuàng)建應(yīng)聘者期望職位
_person.work = new Work(work);
//將創(chuàng)建的應(yīng)聘者對(duì)象返回
return _person;
}
//實(shí)例
var person = new Person('xiao kai', 'code');
//測(cè)試
console.log(person.skill);//保密
console.log(person.name.FirstName);//xiao
console.log(person.work.work);//工程師
console.log(person.work.workDescript);//每天沉醉于編程
person.work.changeDescript('更改一下職位描述!');
console.log(person.work.workDescript);//更改一下職位描述!