创建型设计模式-封装和对象(工厂模式,建造者模式,单例模式)

  • 要点:

  1. 定义变量不会污染外部
  2. 能够作为一个模块调用
  3. 遵循开闭原则
  • 什么是好的封装:

  1. 变量外部不可见
  2. 调用接口使用
  3. 留出扩展接口

 

  • 封装对象时的设计模式

工厂模式

目的:方便我们大量创建对象(大量多个)

应用场景:当某一个对象需要经常创建的时候(分页;弹窗等)

一、基本结构:

function Factory(type){
	switch (type){
		case 'type1':
			return new Type1();
		case 'type2':
			return new Type2();
		case 'type3':
			return new Type3();
	}
}

ps:工厂模式就是写一个方法,只需要调用这个方法,就能拿到你要的对象

 

二、工厂模式示例

例子:实现一个多彩弹框

需求:弹窗有多种,他们之间存在内容和颜色的差异,

// 放在一个匿名自执行函数,向外部暴露pop
(function(){
// 创建一个弹框工厂
	function pop(type,content,color){
		// 判断使用者是否new了这个弹框,健壮性
		if(this instanceof pop){
				return new this[type](content,color)
			}else{
				return new pop(type,content,color)
			}
		}
	pop.prototype.infoPop = function(){}
	pop.prototype.confirmPop = function(){}
	pop.prototype.cancelPop = function(){}
	window.pop = pop
})()
// 外部直接调用
pop('infoPop','hello','blue')

例子:源码示例jQuery

需求:jQuery需要操作dom,每一个dom都是一个jq对象, 

(function(){
	var jQuery = function(selectory,context){
		// 参数接受选择器和上下文
		
		// 内部其实返回了这么一个init对象,假如new了本身会递归循环
		return new jQuery.fn.init(selectory,context);
	};
	jQuery.fn = jQuery.prototype = {
		init:function(){
			
		}
	}
	jQuery.fn.init.prototype = jQuery.fn;
	// jq的各种方法模块扩展进去 extend方法 作用:拷贝
	jQuery.extend = jQuery.fn.extend = function(){
		
	}
	jQuery.extend({
		
	})
	// 挂载到window
	window.$ = window.jQuery = jQuery;
})();

 

建造者模式

目的:需要组合出一个全局对象(精细化一个)
应用场景:当要创建单个又庞大的组合对象时(轮播图)

一:基本结构

//模块1
function Mode1(){
	
}
//模块2
function Mode2(){
	
}
// 最终的使用类
function Final(){
	this.mode1 = new Mode1();
	this.mode2 = new Mode2();
}

ps:把一个复杂的类各个部分,拆分成独立的类,然后再在最终类里组合到一块,Final为最终给出去的类

 

二:建造者模式示例

例子:编辑器插件
需求:有一个编辑器插件,初始化的时候需要大量参数,而且内部功能很多,

// 最终new的编辑器类
function Editor(){
	// 初始化
	this.initHtml = new initHtml();
	this.fontControll = new fontControll();
	this.stateControll = new stateControll();
};
// 初始化html类
function initHtml(domStyle){
  this.template='<div style={{editorStyle}}><div></div><div><textarea style={{areaSyle}}/></div></div>';
}

initHtml.prototype.initStyle = function(){
	
}
initHtml.prototype.renderDom = function(){
	
}
// 字体控制类
function fontControll(){
	
}
fontControll.prototype.changeColor = function(){
	
}
fontControll.prototype.changeFontsize = function(){
	
}
// 状态控制类
function stateControll(){
	// 假设有个状态数组和当前状态index
	this.state = [];
	this.nowstate = 0
}
stateControll.prototype.saveState = function(){
	
}
stateControll.prototype.stateBack = function(){
	// 我们可以直接操作其他类
	var state = this.state[this.nowstate-1];
	this.fontControll.changeColor(state.color);
	this.fontControll.changeFontsize(state.color);
}
stateControll.prototype.stateGo = function(){
	
}
window.Editor = Editor;

例子:Vue初始化
需求:内部众多模块,过程复杂

function Vue(){
	if(!(this instanceof Vue)){
		// 你需要new操作符
		warn('Vue is a constructor and should be called with the `new` keyword');
	};
	// 传入用户配置参数初始化
	this._init(options);
}

// 用方法混入实例
initMixin(Vue);
stateMixin(Vue);
eventsMixin(Vue);
lifecycleMixin(Vue);
renderMixin(Vue);

export function install (_Vue) {
  if (Vue && _Vue === Vue) {
	if (process.env.NODE_ENV !== 'production') {
	  console.error(
		'[vuex] already installed. Vue.use(Vuex) should be called only once.'
	  )
	}
	return
  }
  Vue = _Vue
  applyMixin(Vue)
}

 

单例模式

目的:需要确保全局只有一个对象
应用场景:为了避免重复新建,避免多个对象存在互相干扰

一:基本结构

//我们要实例化的对象
let Singleton = function(name){
	this.name = name;
}
//在singleton上挂载一个getInstance方法
Singleton.getInstance = function(name){
	// 如果已经实例化过了就直接返回instance
	if(this.instance){
		return this.instance
	}
	// 定义instance为实例化对象返回
	return this.instance = new Singleton(name);
}

ps:通过定义一个方法,使用时只允许通过此方法拿到存在内部的同一实例化对象,单例模式写法不固定,

 

二:单例模式示例

例子:写一个全局数据储存对象
需求:这个储存者只有一个,不然得进行同步,增加复杂度

function store(){
	// 判断有没有静态的install属性
	if(store.install){
		return store.install;
	}
	// 没有就把他指向this 对象本身
	store.install = this;
	
	this.store = {
		
	}
}
store.install = null;

例子:Vue-router

需求:保障只有一个

// 现在外层定义个_Vue变量
let _Vue;
function install (_Vue) {
	// 判断有没有installed的属性并且_Vue被赋值过了
	if (install.installed && _Vue === Vue) return
	install.installed = true
  
	_Vue = Vue
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值