前言
设计模式,英文Design Pattern 简单来说,就是前人在解决问题的时候,遇到相似的问题,频繁地遇到,每次都要写相同的代码,好烦,重复的工作太多。于是就在想能不能将这种重复的代码组织一下,用某一种东西,把它自动化,不用每次都做这么多重复的事,这就是设计模式
当然这只是设计模式的一部分问题,还有一部分是怎么让代码更好的维护、有更高的复用性、让代码更加稳健;但一种设计模式不能解决所有问题,所以会多种设计模式,其重点各不同。其中创建类相关的设计模式有:
- 构造器模式
- 原型模式
- 构建者模式
- 工厂模式
- 抽象工厂模式
- 单例模式
几种设计模式
构造器模式
//创建一个类,来统一构造对象
function Student(name,gender,score){
this.name=name;
this.gender=gender;
this.score=score;
this.qulity=100;
this.sumScore=function(){
return this.score + this.qulity;
}
}
var alice = new Student('alice','女',80);
var tom = new Student('tom','男',88);
console.log(alice,tom);
//es6
class Student{
constructor(name,gender,score){
this.name=name;
this.gender=gender;
this.score=score;
this.quality=100;
}
sumScore(){
return this.score + this.qulity;
}
}
let alice = new Student('alice','女',80);
let tom = new Student('tom','男',88);
console.log(alice,tom);
原型模式
function Student(name,gender,score){
this.name = name;
this.gender = gender;
this.score = score;
}
//利用原型提取共有属性和方法,不用放在构造器里每次都要执行代码
Student.prototype.quality = 100;
Student.prototype.sumScore = function (){
return this.score + this.qulity;
}
var alice = new Student('alice','女',80);
var tom = new Student('tom','男',88);
console.log(alice,tom);
原型模式应用
<script type="text/javascript">
var rootElement = document.getElementById('table_roster');
//构造器
function Student(name,gender,score){
this.name = name;
this.gender = gender;
this.score = score;
this.mount();
}
//原型中共有属性和方法
Student.prototype.qulity = 100;
Student.prototype.sumScore = function (){
return this.score + this.qulity;
}
//将数据挂载到页面上
Student.prototype.mount = function(){
var tr = document.createElement('tr');
tr.innerHTML='<td>'+this.name+'<td>' +
'<td>'+this.gender+'<td>' +
'<td>'+this.score+'<td>' +
'<td>'+this.qulity+'<td>' +
'<td>'+this.sumScore()+'<td>';
rootElement.appendChild(tr);
}
var alice = new Student('alice','女',80);
var tom = new Student('tom','男',88);
------------------------------------------------------------------------------------------
//es6写法
var rootElement = document.getElementById('table_roster');
class Student{
// 构造器
constructor(name,gender,score){
this.name = name;
this.gender = gender;
this.score = score;
this.quality=100;
this.mount();//执行挂载
}
// 计算总分
sumScore(){
return this.score + this.quality;
}
//挂载
mount(){
var tr = document.createElement('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 alice = new Student('alice','女',80);
var tom = new Student('tom','男',88);
</script>
构建者模式(创建者模式)
function Student(){
}
//构建者类
function StudentBuilder(){
this.student=new Student();
this.setName=function(name){
this.student.name = name;
}
this.setGender=function(gender){
this.student.gender = gender;
}
this.setHairLength=function(hairlength){
this.student.hairlength = hairlength;
}
this.build= function(){
return this.student;
}
}
//创建一个构建者对象来操作
var builder = new StudentBuilder();
builder.setName('alice');
builder.setGender('女');
builder.setHairLength(2);
var alice = builder.build();
console.log(alice);
------------------------------------------------------------------------------------------
//es6写法
class Student{
}
//构建者类
class StudentBuilder{
constructor(){
this.student=new Student();
}
setName(name){
this.student.name = name;
}
setGender(gender){
this.student.gender = gender;
}
setHairLength(hairlength){
this.student.hairlength = hairlength;
}
build(){
return this.student;
}
}
//创建一个构建者对象来操作
let builder = new StudentBuilder();
builder.setName('alice');
builder.setGender('女');
builder.setHairLength(2);
let alice = builder.build();
console.log(alice);
构建者模式应用
<!DOCTYPE html>
<html>
<head>
<title>demo</title>
</head>
<body>
<form id="create">
<div>
姓名:
<input type="text" name="studentName" autofocus><br>
</div>
<div>
性别:
<input type="radio" name="gender" value="女" checked>女
<input type="radio" name="gender" value="男">男
<br>
</div>
<div>
年龄:
<input type="number" name="age">
</div>
<input type="submit" value="提交">
</form>
<script type="text/javascript">
var createForm = document.getElementById('create');
init();
function init(){
createForm.addEventListener('submit',function(e){
e.preventDefault();
var name = document.querySelector('[name="studentName"]').value;
var gender = document.querySelector('[name="gender"]:checked').value;
var age = document.querySelector('[name="age"]').value;
var bulider = new StudentBuilder();
bulider.setName(name);
bulider.setGender(gender);
bulider.setAge(age);
var student = bulider.bulid();
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){
this.student.gender=gender;
}
StudentBuilder.prototype.setAge=function(age){
this.student.age=age;
}
StudentBuilder.prototype.bulid=function(){
return this.student;
}
</script>
</body>
</html>
工厂模式
<script type="text/javascript">
function Student(name,subjects){
this.name=name;
this.subjects=subjects;
}
// 不用var alice = new Student('alice',['政治','历史','地理']),数据多了,每条都要写,太麻烦。
var alice = factory('alice','LIBERAL_ART');
var tom= factory('tom','SCIENCE');
console.log(alice,tom);
// 创建工厂
function factory(name,type){
if (type=='LIBERAL_ART') {
return new Student(name,['政治','历史','地理']);
}else{
return new Student(name,['数学','物理','化学']);
}
}
</script>
----------------------------------------------------------------------------------
//工厂模式的应用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>demo</title>
</head>
<body>
<form id="createStudent">
<div>
姓名:
<input type="text" name="name">
</div>
<div>
<select name="type">
<option value="文科">文科</option>
<option value="理科">理科</option>
<option value="体育">体育</option>
</select>
</div>
<button type="submit">提交</button>
</form>
<script type="text/javascript">
init();
function init(){
var form=document.getElementById('createStudent');
form.addEventListener('submit',function(e){
e.preventDefault();
var name = document.querySelector('[name="name"]').value;
var type = document.querySelector('[name="type"]').value;
var student = studentFactory(name,type);
console.log(student);
});
}
// 类
function Student(name,subjects){
this.name=name;
this.subjects=subjects;
}
// 工厂
function studentFactory(name,type){
if (type=='文科') {
return new Student(name,['政治','历史','地理']);
}else if(type=='理科'){
return new Student(name,['数学','物理','化学']);
}else{
return new Student(name,['长跑','跳绳','跳高']);
}
}
</script>
抽象工厂模式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>demo</title>
</head>
<body>
<script type="text/javascript">
function Student(){
this.intro = '我是个学生';
}
function Teacher(){
this.intro = '我是个老师';
}
function studentFactory(){
return new Student();
}
function teacherFactory(){
return new Teacher();
}
//抽象工厂,本省不生产东西,而是在组织工厂。
function userAbstractFactory(factory){//或者叫userProducer
switch(factory){
case 'student':
return studentFactory;
break;
case 'teacher':
return teacherFactory;
break;
default:
throw '没有这个工厂';
break;
}
}
var factory=userAbstractFactory('student');
console.log(factory());
</script>
</body>
</html>
单例模式
无论怎么new只返回一份实例,第二次new是返回第一次new好的对象。
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.balance=50;
console.log(r);
//....