首页 > 代码库 > javascript设计模式——单体模式
javascript设计模式——单体模式
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>测试文档</title>
<script>
// 单体模式的定义:一个只能实例化一次的类,并且提供一个众所周知的全局访问点。
// 单体模式的作用:面向对象编程的思考方式,就是对现实生活的具体对象抽象化。————即建模
// 对于现实生活来说,很多对象只有一个是很重要的。比如说,一个公司只能有一个会计系统,一个数字滤波器只能有一个模数转换器
//一台计算机只应该有一个文件系统和窗口管理器。对应到抽象的面向对象编程的世界里,就是有些类只应该有一个实例。
// 单体模式的实现:让类自身负责保存它的唯一实例。(这个类可以保证只能创建一个实例,并且有一个可访问该实例的方法)
//
// 单体模式在js中的实现有两种方式。一,对象字面量。二,闭包。
//
// 方式一:使用对象字面量形式的单体
//在js中没有类的概念。js是通过对象实例化对象的。
//因此,你可以把Singleton看作是一个类,并且实现了一个唯一的对象。(可能有点绕)
//此外,我们可以通过Singleton.name,Singleton.getName等点操作符来实现对实例的访问。
// 对象字面量创建的单体的应用。 ————封装
// 封装————命名空间的使用
//通过将数据和方法都封装在一个对象内部
//这样就保护了外部的同名变量不会被意外重写。当本地代码作为第三方js库使用时也不会影响对方的本地代码的变量。————命名空间的作用
// 假设这是加载第三方js库内定义的变量
var name=‘Elvis‘;
// 本地js代码
var Singleton={
name:‘Byronvis‘,
getName:function(){
alert( this.name);//有时候会出错
alert(Singleton.name);//最好使用这种方式
}
};
Singleton.getName();
// 不使用单体模式的情况下很容易意外重写变量
// 假设这是加载第三方js库内定义的变量
var name="Elvis";
// 本地js代码
var name=‘Byronvis‘;//意外重写了第三方js库的对象
var getName=function(){
alert(name);
};
getName();
// 封装————代码包装器
//在拥有许多网页的网站中,有些js代码是所有网页都需要的,它们通常都放在独立的文件中,
//而有些代码是某个网页专用的,不会被用到其他地方。最好把这两种代码分别包装在自己的单体中。
//换句话说,就是可以把几个不常用的功能块封装在一个单体中。
// 方式二:通过闭包创建单体。
//之前通过对象字面量创建的单体有一些缺点。就是单体对象的数据和方法都是公有的,没有私有属性。
//通过闭包就可以实现对象的私有属性。
SecondSingleton=(function(){
// 对象的私有数据
var name=‘Elvis‘;
// 对象的私有方法
function setName(){
name=‘Byron‘
}
return {
// 对象的公有数据
location:‘Hangzhou‘,
// 对象的特权方法
getLocation:function(){
alert(this.location);
},
getName:function(){
alert(name);
}
};
})();
SecondSingleton.getName();
// 闭包方式创建单体的应用。 ————分支
//分支的作用:
//浏览器之间是有差异的。针对于某个功能,不同的浏览器有不同的实现方式
//我们把每个浏览器的实现方式进行封装,并在页面加载js文件时,通过能力测试或者浏览器嗅探来动态决定使用哪种方式实现该功能。
_SecondSingleton=(function(){
var objA={
age:22,
getAge:function(){
alert(‘age:‘+this.age);
}
};
var objB={
age:23,
getAge:function(){
alert(this.age);
}
};
// 约束条件,实现分支的根本
return (2>1)?objA:objB;
})();
_SecondSingleton.getAge();
// 惰性实例化单体
//之前两种方式创建的单体,都有一个共同点,当网页加载好js文件后会立即实例化单体。
// (源于对象字面量方式直接在全局环境中定义,闭包方式的函数也是定义后立即执行)
//对于单体实例比较大的单体,我们有时候希望其在使用时实例化,不希望过早实例化占用资源。
//这时候就需要惰性实例化单体了。
// 惰性实例化单体的思路:闭包内嵌闭包
//将实例的构造器这个闭包外层再包围一个闭包。
//通过外层闭包的特权方法实现对构造器的控制。
//此时访问单体的属性方法就发生了改变。
//由此也可以看出惰性实例化单体的主要缺点就是复杂。不如前两种来的直观些。
ThirdSingleton=(function() {
// 用于保存实例的私有变量
var instance;
return{
// 调用实例化方法(通过这个方法实现对实例化单体的时间控制)
getInstance:function(){
// 若实例不存在则实例化对象
if(!instance){
instance=Constructor();
}
// 若实例存在则返回实例
return instance;
}
};
//单体实例的构造器
function Constructor() {
// 对象的私有数据
var name = ‘Elvis‘;
// 对象的私有方法
function setName() {
name = ‘Byron‘
}
return {
// 对象的公有数据
location: ‘Hangzhou‘,
// 对象的特权方法
getLocation: function () {
alert(this.location);
},
getName: function () {
alert(name);
}
}
}
})();
// 访问单体的属性的方法改变,必须有getInstance()前缀
ThirdSingleton.getInstance().getLocation();
</script>
</head>
<body>
这真的只是一个测试文档啊。
</body>
</html>
javascript设计模式——单体模式