今天跟大家聊聊开发过程中用到的几种设计模式。包括在校招,社招面试的时候都要问到的一些设计模式。
先看文章,如果还是不怎么理解跟明白的话,你可以回头看看这个视频讲解:设计模式详解
面向对象的实现
设计模式便是面向对象的深入,面向对象的应用,所以类的实现是第一步:
PS:这里依赖了underscore,各位自己加上吧。
1 //window._ = _ || {};
2 // 全局可能用到的变量
3 var arr = [];
4 var slice = arr.slice;
5 /**
6 * inherit方法,js的继承,默认为两个参数
7 *
8 * @param {function} origin 可选,要继承的类
9 * @param {object} methods 被创建类的成员,扩展的方法和属性
10 * @return {function} 继承之后的子类
11 */
12 _.inherit = function (origin, methods) {
13
14 // 参数检测,该继承方法,只支持一个参数创建类,或者两个参数继承类
15 if (arguments.length === 0 || arguments.length > 2) throw '参数错误';
16
17 var parent = null;
18
19 // 将参数转换为数组
20 var properties = slice.call(arguments);
21
22 // 如果第一个参数为类(function),那么就将之取出
23 if (typeof properties[0] === 'function')
24 parent = properties.shift();
25 properties = properties[0];
26
27 // 创建新类用于返回
28 function klass() {
29 if (_.isFunction(this.initialize))
30 this.initialize.apply(this, arguments);
31 }
32
33 klass.superclass = parent;
34
35 // 父类的方法不做保留,直接赋给子类
36 // parent.subclasses = [];
37
38 if (parent) {
39 // 中间过渡类,防止parent的构造函数被执行
40 var subclass = function () { };
41 subclass.prototype = parent.prototype;
42 klass.prototype = new subclass();
43
44 // 父类的方法不做保留,直接赋给子类
45 // parent.subclasses.push(klass);
46 }
47
48 var ancestor = klass.superclass && klass.superclass.prototype;
49 for (var k in properties) {
50 var value = properties[k];
51
52 //满足条件就重写
53 if (ancestor && typeof value == 'function') {
54 var argslist = /^\s*function\s*\(([^\(\)]*?)\)\s*?\{/i.exec(value.toString())[1].replace(/\s/i, '').split(',');
55 //只有在第一个参数为$super情况下才需要处理(是否具有重复方法需要用户自己决定)
56 if (argslist[0] === '$super' && ancestor[k]) {
57 value = (function (methodName, fn) {
58 return function () {
59 var scope = this;
60 var args = [
61 function () {
62 return ancestor[methodName].apply(scope, arguments);
63 }
64 ];
65 return fn.apply(this, args.concat(slice.call(arguments)));
66 };
67 })(k, value);
68 }
69 }
70
71 //此处对对象进行扩展,当前原型链已经存在该对象,便进行扩展
72 if (_.isObject(klass.prototype[k]) && _.isObject(value) && (typeof klass.prototype[k] != 'function' && typeof value != 'fuction')) {
73 //原型链是共享的,这里处理逻辑要改
74 var temp = {};
75 _.extend(temp, klass.prototype[k]);
76 _.extend(temp, value);
77 klass.prototype[k] = temp;
78 } else {
79 klass.prototype[k] = value;
80 }
81
82 }
83
84 if (!klass.prototype.initialize)
85 klass.prototype.initialize = function () { };
86
87 klass.prototype.constructor = klass;
88
89 return klass;
90 };
使用测试:
1 var Person = _.inherit({
2 initialize: function(opts) {
3 this.setOpts(opts);
4 },
5
6 setOpts: function (opts) {
7 for(var k in opts) {
8 this[k] = opts[k];
9 }
10 },
11
12 getName: function() {
13 return this.name;
14 },
15
16 setName: function (name) {
17 this.name = name
18 }
19 });
20
21 var Man = _.inherit(Person, {
22 initialize: function($super, opts) {
23 $super(opts);
24 this.sex = 'man';
25 },
26
27 getSex: function () {
28 return this.sex;
29 }
30 });
31
32 var Woman = _.inherit(Person, {
33 initialize: function($super, opts) {
34 $super(opts);
35 this.sex = 'women';
36 },
37
38 getSex: function () {
39 return this.sex;
40 }
41 });
42
43 var xiaoming = new Man({
44 name: '小明'
45 });
46
47 var xiaohong = new Woman({
48 name: '小红'
49 });
xiaoming.getName()
"小明"
xiaohong.getName()
"小红"
xiaoming.getSex()
"man"
xiaohong.getSex()
"women"
单例模式(Singleton)
单列为了保证一个类只有一个实例,如果不存在便直接返回,如果存在便返回上一次的实例,其目的一般是为了资源优化。
javascript中实现单例的方式比较多,比较实用的是直接使用对象字面量:
1 var singleton = {
2 property1: "property1",
3 property2: "property2",
4 method1: function () {}
5 };
类实现是正统的实现,一般是放到类上,做静态方法:
在实际项目中,一般这个应用会在一些通用UI上,比如mask,alert,toast,loading这类组件,还有可能是一些请求数据的model,简单代码如下:
1 //唯一标识,一般在amd模块中
2 var instance = null;
3
4 //js不存在多线程,这里是安全的
5 var UIAlert = _.inherit({
6 initialize: function(msg) {
7 this.msg = msg;
8 },
9 setMsg: function (msg) {
10