javascript --- > 使用对象关联简化整体设计

在某个场景中,我们有两个控制器对象:
1.用来操作网页中的登录表单;
2.用来与服务器进行通信.

类设计模式

// 把基础的函数定义在名为Controller的类中,然后派生两个子类LoginController和AuthController.
// 父类
function Controller() {
    this.errors = [];
}
Controller.prototype.showDialog = function(title, msg) {
    // 给用户显示标题和消息
};
Controller.prototype.success = function(msg) {
    this.showDialog("Success", msg);
};
Controller.prototype.failure = function(err) {
    this.error.push(err);
    this.showDialog("Error", err);
};

// 子类
function LoginController() {
    Controller.call(this);
}
// 把子类关联到父类
LoginController.prototype = Object.create(Controller.prototype);
LoginController.prototype.getUser = function() {
    return document.getElementById("login_username").value;
};
LoginController.prototype.getPassword = function() {
    return document.getElementById("login_password).value;
};
LoginController.prototype.validateEntry = function (user, pw) {
    user = user || this.getUser();
    pw = pw || this.getPassword();
     
    if(!(user && pw)) {
        return this.failure(
            "Please enter a username & password!"
        );
    }
    else if (pw.length < 5) {
        return this.failure(
            "Password must be 5+ characters!"
        );
    }
     
    // return true;
};

// 重写基础failure()
LoginController.prototype.failure = function(err) {
    Controller.prototype.failure.call(
        this,
        "Login invalid: " + err
    );
};

// 子类
function AuthController(login) {
    Controller.call(this);
    // 合成
    this.login = login;
}
// 把子类关联到父类
AuthController.prototype = Object.create(Controller.prototype);
AuthController.prototype.server = function (url, data){
    return $.ajax({
        url: url,
        data: data
    });
};
AuthController.prototype.checkAuth = function() {
    var user = this.login.getUser();
    var pw = this.login.getPassword();
     
    if(this.login.validateEntry(user,pw)) {
        this.server('/check-auth',{
            user:user,
            pw: pw
        })
        .then(this.success.bind(this))
        .fail(this.failure.bind(this));
    }
};
// 重写基础success()
AnthController.prototype.success = function() {
    Controller.prototype.success.call(this, "Authenticated!");
};
// 重写基础的failure()
AuthController.prototype.failure = function(err) {
    Controller.prototype.failure.call(this, "Auth Failed: " + err);
};
     
var auth = new AuthController(
    new LoginController() // 合成...
};
auth.checkAuth();

对象关联的设计:

var LoginController = {
    errors: [],
    getUser: function() {
        return document.getElementById("login_username").value;
    },
    getPassword: function() {
        return document.getElementById("login_password").value;
    },
    validateEntry: function(user, pw) {
        user = user || this.getuser();
        pw = pw || this.getPassword();
         
        if(!(user && pw)) {
            return this.failure("Please enter a username & password!"
            );
        }
        else if(pw.length < 5) {
            return this.failure("Password must be 5+ characters!");
        }
        // 执行到这里说明通过验证
        return true;
    },
    showDialog: function(title, msg) {
        // 给用户显示标题和消息
    },
    failure: function(err) {
        this.error.push(err);
        this.showDialog("Error", "Login invalid: " + err);
    }
};
// 让AuthController委托LoginController
var AuthController = Object.create(LoginController);

AuthController.errors = [];
AuthController.checkAuth = function() {
    var user = this.getUser();
    var pw = this.getPassword();
     
    if(this.validateEntry(user, pw)) {
        this.server('/check-auth", { 
            user:user,
            pw:pw
        })
        .then(this.accepted.bind(this))
        .fail(this.rejected.bind(this));
    }
};
AuthController.server = function(url, data) {
    return $.ajax({
        url: url,
        data: data
    });
};
AuthController.accepted = function() {
    this.showDialog("Success" , " Authenticated!");
};
AuthController.rejected = function(err){
    this.failure("Auth Failed: " + err);
};
// 借助对象关联,可以简单地向委托链上添加一个或多个对象.
var controller1 = Object.create(AuthController);
var controller2 = Object.create(AuthController);

更好的语法:

// 在ES6中,可以使用对象字面量的形式来改写繁琐的属性赋值语法
var LoginController = {
    errors: [],
    getUser() {
        //...
    },
    getPassword() {
        //...
    }
    //...
};
var AuthController = {
    errors: [],
    checkAuth() {
        //...
    },
    server(url, data) {
        //...
    }
    // ...
};

// 使用Object.setProtptypeOf(...)来修改其原型链[[Prototype]]
Object.setPrototypeOf(AuthController, loginController);

参考《你不知道的JavaScript》(上卷)P178~P183

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值