几种设计模式

1,543 阅读2分钟

前言

设计模式,英文Design Pattern 简单来说,就是前人在解决问题的时候,遇到相似的问题,频繁地遇到,每次都要写相同的代码,好烦,重复的工作太多。于是就在想能不能将这种重复的代码组织一下,用某一种东西,把它自动化,不用每次都做这么多重复的事,这就是设计模式

当然这只是设计模式的一部分问题,还有一部分是怎么让代码更好的维护、有更高的复用性、让代码更加稳健;但一种设计模式不能解决所有问题,所以会多种设计模式,其重点各不同。其中创建类相关的设计模式有:

  1. 构造器模式
  2. 原型模式
  3. 构建者模式
  4. 工厂模式
  5. 抽象工厂模式
  6. 单例模式

几种设计模式

构造器模式

//创建一个类,来统一构造对象
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);
//....