JavaScript设计模式(biaoyansu)

1.构造器模式——创建类模式

 

ES6:
class Student{
constructor(score,quality){
this.score = score
this.quality = quality
}
sumScore(){
return this.score + this.quality
}
}

ES5:
function Student(name,gender,score){
this.name = name;
this.gende = gender;
this.score = score;
this.quality = 100;

this.sumScore = function() {
return this.score + this.quality
}
}

 

面向对象的思想

每个对象可以随着事件的推移自己内在发生变化而不去影响其他对象

 

2.原型模式——创建类模式

 

// 如果是王花花和李栓蛋两个对象,没必要每个人都有一个sumScore这个函数,引用同一个就行

function Student(name,gender,score){
this.name = name;
this.gende = gender;
this.score = score;
this.quality = 100;

this.sumScore = sumScore
}

 

 function sumScore() {
 return this.score + this.quality
}

 

使用原型模式书写:

function Student(name,gender,score){
this.name = name;
this.gende = gender;
this.score = score;
this.quality = 100;

}

Student.prototype.sumScore =  function(){

 return this.score + this.quality

}

 

原型模式的应用:

roster(花名册、记事簿 bu) rooster(公鸡🐓

<table id = 'roster'>
</table>


var root Element = document.getElementById('roster')

function Student(name,gender,score){
this.name = name
this.gender = gender
this.score = score
this.quality = 100
}

Student.prototype.sumScore() = function(){
return this.score + this.quality
}

// 将数据转换为HTML并插入到表格种
Student.prototype.mount = function(){
var tr = document.createElement('tr)
console.log('tr:',tr)
tr.innerHTML =
'<td>' + this.name + '</td>' +
'<td>' + this.gender+ '</td>' +
'<td>' + this.score + '</td>' +
'<td>' + this.quality + '</td>' +
'<td>' + this.sumScore()+ '</td>' ;

rootElement.appendChild(tr)

}

 

var whh = new Student('whh','male',98)
var lsd = new Student('lsd','fmale',50)

whh.mount()
lsd.mount()


// 或者可以搞的更方便 可以在function Student中写 this.mount()
// 这样new 出来的时候就连带着自动mount上了

 

原型模式的应用(es6):

class Student{

constructor(name,gender,score){
this.name = name
this.gender = gender
this.score = score
this.quality = 100
}

sumScore(){
return this.score + this.quality
}

mount() {
...
  }
}

 

var whh = new Student('whh','male',98)
var lsd = new Student('lsd','fmale',50)

whh.mount()
lsd.mount()

 

 

3.构建者模式——创建类模式

 

之前讲了原型模式:
当需要重复的生成一类对象的时候使用原型模式
本节讲解构建者模式

function Student(name,gender){
}


var whh = new Student()
var length = 2
var gender = '男'
whh.name = '王花花'


if(gender != '男' && gender != '女')
throw '好玩不'

whh.gender = '男'

if(
whh.gender === '男' && length >1) ||
whh.gender === '女' && length >25
)
throw '回去剪头'


whh.hairLength = length

console.log(whh)

这样写太乱了,结构也不好,现在寻求一种更好的方法。


var studentCount = 0

function Student(){

}

function StudentBuilder() {
this.student = new Student()
this.setName = function(name){
this.student.name = name
}
this.setGender = function(gender){
if(gender ! = '男' && gender != '女')
throw '好玩不'
this.student.gender = gender
}
this.setHairLength = function(hairLength){
if(
(this.student.gender == '男' && (hairLength)>1 ) ||
(this.student.gender == '女' && (hairLength)>25)
)
this.student.hairLength = hairLength
}
this.build = function(){
studentCount++
console.log(studentCount)
return this.student
}
}

// 构建者 构建者是一个工人,工人在操作这个机器
var builder = new StudentBuilder()
builder.setName('王花花')
builder.setGender('男')
builder.setHairLength('2')
var whh = builder.build()

console.log(whh)

**************
在之前的模式中,本质是创建一个对象,然后给对象的属性赋值
//var x = {}
x.a = ..
x.b = ..

设置属性的这个过程程序的其他地方是不知道的

现在使用构建者模式,一旦某个值发生改变,程序就会得到通知这个地方得到改变了。

 

let studentCount = 0;

class Student {
}

class StudentBuilder {
constructor() {
this.student = new Student();
}

setName(name) {
this.student.name = name;
}

setGender(gender) {
if (gender != '男' && gender != '女')
throw '好玩不';

this.student.gender = gender;
}

setHairLength(hairLength) {
if (
(this.student.gender == '男' && hairLength > 1) ||
(this.student.gender == '女' && hairLength > 25)
) throw '回去剪头';

this.student.hairLength = hairLength;
}

build() {
studentCount++;
console.log(studentCount);
return this.student;
}
}

const builder = new StudentBuilder();
builder.setName('王花花');
builder.setGender('男');
builder.setHairLength(1);
const whh = builder.build();

const builder2 = new StudentBuilder();
builder2.setName('李拴蛋');
builder2.setGender('女');
builder2.setHairLength(20);
const lsd = builder2.build();

console.log(lsd);

 

构建者模式的应用

<form id = ‘create’>

   <div>

      姓名

<input type=’’test name = name>

       </div>

<div>

  性别

      <input type=’radio’ name=’gender’ value=’女’ checked>女

      <input type=’radio’ name=’gender’ value=’男’>男

     </div>

<div>

   头发长度

   <input type = ‘number’ name=’hairLength’>

 </div>

 <button type=’submit’>创建学生</button>

</form>

 

<script>

 

var createForm = document.getElementById(‘create’)

  

 init()

 

function init() {

  createForm.addEventListener(‘submit’,function (e){

     e.preventDefault()

     var name = document.querySelector(‘[name=name]’).value)

var gender = document.querySelector(‘[name=gender]:checked’).value

var hairLength = document.querySelector(‘[name=hairLength]’).vale

 

console.log(name,gender,hairLength)

 

try{

       var builder = new StudentBuilder()

builder.setName(name)

builder.setGender(gender)

builder.setHairLength(hairLength)

var student = builder.build()

} catch(e) {

  alert(e)

}

 

 

console.log(student)

})

}

 

 

 

function Student() {

  }

 

  function StudentBuilder() {

    this.student = new Student();

  }

 

  StudentBuilder.prototype.setName = function (name) {

    this.student.name = name;

  }

 

  StudentBuilder.prototype.setGender = function (gender) {

    if (gender != '男' && gender != '女')

      throw '好玩不';

 

    this.student.gender = gender;

  }

 

  StudentBuilder.prototype.setHairLength = function (hairLength) {

    if (

      (this.student.gender == '男' && hairLength > 1) ||

      (this.student.gender == '女' && hairLength > 25)

    ) throw '回去剪头';

 

    this.student.hairLength = hairLength;

  }

 

  StudentBuilder.prototype.build = function () {

    return this.student;

  }

 

</script>

 

4.工厂模式——创建类模式

function student(name,subjects){

 this.name = name

// 如果是文科生['政治 历史 地理]

// 如果是理科生[数学 物理 化学]

 this.subjects = subjects

}

var whh = new Student('王花花',['政治,'历史,'地理])

console.log(whh)

 

function factory(name,type) {

 

   switch(type) {

       case '文科':

            return new Student (name,['政治,'历史,'地理

            break

       case '理科 

               return new Student(name,['数学,'物理','化学

             break

          case '体育'

             return new Student(name,['长跑,‘...

             break

           default

              throw '没有这个专业 别瞎填

   }

}

 

var whh = factory('whh','文科'

var lsd = factory('李栓但','理科

 // 工厂模式 可以生成几类对象,每次返回的都是新对象 你把钱给它,它会一批批的出货

 

 工厂模式的应用

<form id="create">
<div>
姓名:
<input type="text" name="name">
</div>
<div>
专业:
<select name="type">
<option value="文科">文科</option>
<option value="理科">理科</option>
<option value="体育">体育</option>
</select>
</div>
<div>
<button type="submit">创建用户</button>
</div>
</form>
 
<script>
init();
 
/**
* 初始化
* */
function init() {
// 获取表单元素,等着绑事件
var form = document.getElementById('create');
 
// 给表单绑提交事件
form.addEventListener('submit', function (e) {
e.preventDefault();
 
// 获取姓名和专业
var name = document.querySelector('[name=name]').value;
var type = document.querySelector('[name=type]').value;
 
// 造学生
var student = factory(name, type);
 
// 重置表单
form.reset();
 
console.log('student:', student);
});
}
 
function Student(name, subjects) {
this.name = name;
// ...
 
// 如果是文科生:['政治', '历史', '地理']
// 如果是理科生:['数学', '物理', '化学']
this.subjects = subjects;
}
 
/**
* 创建学生
* @param {string} name 姓名
* @param {string} type 文科还是理科
* @return {Student}
*/
function factory(name, type) {
 
switch (type) {
case '文科':
return new Student(name, ['政治', '历史', '地理'])
break;
case '理科':
return new Student(name, ['数学', '物理', '化学'])
break;
case '体育':
return new Student(name, ['长跑', '...'])
break;
default:
throw '没有这个专业,别瞎填';
}
}
</script>
 
ES6 转换:
<form id="create">
<div>
姓名:
<input type="text" name="name">
</div>
<div>
专业:
<select name="type">
<option value="文科">文科</option>
<option value="理科">理科</option>
<option value="体育">体育</option>
</select>
</div>
<div>
<button type="submit">创建用户</button>
</div>
</form>
 
<script>
init();
 
/**
* 初始化
* */
function init() {
const form = document.getElementById('create');
 
form.addEventListener('submit', e => {
e.preventDefault();
 
const name = document.querySelector('[name=name]').value;
const type = document.querySelector('[name=type]').value;
 
const student = factory(name, type);
form.reset();
 
console.log('student:', student);
});
}
 
class Student {
constructor(name, subjects) {
this.name = name;
// ...
 
// 如果是文科生:['政治', '历史', '地理']
// 如果是理科生:['数学', '物理', '化学']
this.subjects = subjects;
}
}
 
/**
* 创建学生
* @param {string} name 姓名
* @param {string} type 文科还是理科
* @return {Student}
*/
function factory(name, type) {
 
switch (type) {
case '文科':
return new Student(name, ['政治', '历史', '地理'])
break;
case '理科':
return new Student(name, ['数学', '物理', '化学'])
break;
case '体育':
return new Student(name, ['长跑', '...'])
break;
default:
throw '没有这个专业,别瞎填';
}
}
</script>
 
 
 
5.抽象工厂模式——创建类模式
function Student () {
this.intro = '我是个学生';
}

function Teacher () {
this.intro = '我是个老师';
}

/**
* 生产学生
* @param {string} factory
*/
function studentFactory () {
return new Student();
}

/**
* 生产老师
* @param {string} factory
*/
function teacherFactory () {
return new Teacher();
}

/**
* 选择工厂
* @param {string} factory
*/
function userProducer (factory) {
// 判断工厂类型
switch (factory) {
case 'student':
return studentFactory;
break;
case 'teacher':
return teacherFactory;
break;
default:
throw '没有这个工厂';
break;
}
}

var factory = userProducer('teacher');
var t = factory('王花花', '特级');
console.log(t);
 
 
6.单例模式——创建类模式
function Resource() {
// 如果不是第一次new (instance肯定是存在的)
if(Resource.instance)
return Resource.instance;
else { // 否则(instance不存在)
// 组装新对象
this.balance = 100
// 将其存到Resource机器上
Resource.instance = this
}
}

var r = new Resource()
console.log('r:',r)
r.balance = 50
console.log('r:',r)
var r2 = new Resource()
console.log('r2:',r2)
r.balance = 55
console.log('r2:',r2)
 
ES6:
class Resource{
constructor() {
// 如果不是第一次new(instance肯定是存在的)
if(Resource.instance)
return Resource.instance;
else { // 否则(instance不存在)
// 组装新对象
this.balance = 100
// 将其存到Resource机器上
Resource.instance = this
}
}
}

const r = new Resource()
console.log('r:',r)
r.balance = 50
console.log('r:',r)
const r2 = new Resource()
console.log('r2:',r2)
r.balance = 55
console.log('r2:',r2)
 
 
 
 
单例模式应用:

 

 

posted @ 2018-09-14 22:18  hh9515  阅读(371)  评论(0编辑  收藏  举报