【设计模式】代理模式

定义

  • 为一个对象提供一个代理以控制对这个对象的访问
  • 代理对象的作用类似于中介,会增加一些功能(校验,合并等),也会去掉原有对象的一些功能。

分类

虚拟代理

  • 虚拟代理是把一些开销很大的对象,延迟到真正需要它的时候才去创建执行。
  • 一般用在图片加载,文件上传等

安全代理

  • 控制真实对象的访问权限
  • 前端校验,登录之后才能看全功能

远程代理

  • 一个对象将不同空间的对象进行局部代理
  • 监控多个对象的状态,总机监控分店

智能代理

  • 调用对象代理处理一些事情,如垃圾回收机制,增加额外的服务
  • 提供额外的其他服务,火车站代售处

实例1 当女神心情好的时候才送花

var mrDeng = {
	sendFlower: function(target){
		var flower = 'sunflower';
		target.receviceFlower(flower);
	}
};
var goddess = {
	mood: null,
	receiveFlower:function(flower){
		this.mood?console.log('ok'):console.log('get out');
	},
	createMood:function(){
		this.mood = Math.random()>0.5;
	}
	changeMood:function(){
		this.createMood();
		setInterval(()=>{
			this.createMood();
		},300)
	}
};
var chengProxy = {
	proxyFlower: function(target){
		this.listenMood(target,function(){
			mrDeng.sendFlower(target);
		})
	},
	listenMood: function(target,cb){
		var timer = setInterval(()=>{
				if(target.mood){
					cb();
					clearInterval(timer);
				}
		},300)
	}
}

实例2 图片加载

var MyImage = function () {
            // document.createElement('img');
            var oImg = new Image();
            this.setSrc = function (src) {
                oImg.src = src;
            }
            document.body.appendChild(oImg);
        }

        var ProxyImage = (function () {
            var oMyImage = new MyImage();
            var oNewImage = new Image();
            oNewImage.onload = function () {
                oMyImage.setSrc(oNewImage.src);
            }
            return function (src) {
                oMyImage.setSrc('占位图片');
                oNewImage.src = src;
            }
        })()
        ProxyImage('需要加载的图片地址');

<div id="demo"></div>
    <script>
        function MyImage(_id){
            var img = document.createElement('img');
            this.setSrc = function(_url){
                img.src = _url;
            }
            document.getElementById('demo').appendChild(img);
        }
        var ProxyImage = function(_src){
            var oImg = new Image();
            var myImage = new MyImage('demo');
            // 刚开始显示的图片
            myImage.setSrc('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1603966982053&di=81fc3058b2ee853efcd66cd39d2f93c2&imgtype=0&src=http%3A%2F%2Fi1.letvimg.com%2Flc03_qmt%2F201708%2F23%2F07%2F52%2Fvidxsujfcl6j%2F169.jpg');
            oImg.onload = function(){
                // 模拟网速不好的时候
                setTimeout(function(){
                    myImage.setSrc(_src);
                },2000)
            }
            oImg.src = _src;
        }
        // 真正需要加载的容量大的图片
        ProxyImage('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1603969277409&di=4fe9d2805f410d72053db18c5158cfe0&imgtype=0&src=http%3A%2F%2Fimg3.imgtn.bdimg.com%2Fit%2Fu%3D3195922608%2C2444882263%26fm%3D214%26gp%3D0.jpg')
    </script>

实现点击之后2秒一起改变样式

<div id='show'>Tscn</div>
    <button type="bg">add greenBg</button>
    <button type="cl">add blueColor</button>
    <button type="fs">add fontSize</button>
    <button type="op">add opacity</button>
    <script>
        var oDiv = document.getElementById('show');
        var oButtonArray = document.getElementsByTagName('button');
        var ProxyRequest = function(func){
            var cache = [];
            var timer = null;
            return function(){
                cache.push(this.getAttribute('type')); 
                clearTimeout(timer);
                timer = setTimeout(function(){
                    //
                    func(oDiv,cache);
                    cache = [];
                },2000)

            }
        }
       var realChangeStyle = ProxyRequest(changeStyle);
         
        for(var i = 0; i < oButtonArray.length; i++){
            oButtonArray[i].onclick = realChangeStyle;
        }
        function changeStyle(dom,typeArr){
            var typeObj = {
                bg:['backgroundColor','green'],
                cl:['color','blue'],
                fs:['fontSize','28px'],
                op:['opacity','0.3']
            }
            if(typeArr.constructor == Array){
                typeArr.forEach(function(ele){
                    dom.style[typeObj[ele][0]] = typeObj[ele][1]; 
                })
            }
            else{
                dom.style[typeObj[typeArr][0]] = typeObj[typeArr][1];
            }
        }

代理模式-表单验证

  • 常规写法
<style>
        input{
            /* display: block; */
            margin-top: 10px;
        }
        span{
            color: red;
            display: block;
        }
    </style>
</head>
<body>
    用户名:<input type="text" name="username" id="userDom"/>
    <span id='s1'></span>
    密码:<input type="password" name="password" id="psDom"/>
    <span id='s2'></span>
    <button id="submit">提交</button>
    <script>
        //用户名长度不能大于3 不能为空
        //密码长度不能小于6 不能为空
        var flag = true; // 默认能发送
        submit.onclick = function(){
            s1.innerText = '';
            s2.innerText = '';
            if(userDom.value == ''){
                flag = false;
                s1.innerText = '用户名不能为空';
            } else if( userDom.value.length >3){
                flag = false;
                s1.innerText = '用户名长度不能大于3';
            }
            if(psDom.value == ''){
                flag = false;
                s2.innerText = '密码不能为空';
            } else if(psDom.value.length < 6){
                flag = false;
                s2.innerText = '密码长度不能小于6';
            }
            if(flag){
                request();
            }
        }
        function request(){

        }
    
    </script>
  • 利用代理模式和策略模式
用户名:<input type="text" name="username" id="userDom" />
    <span id='s1'></span>
    密码:<input type="password" name="password" id="psDom" />
    <span id='s2'></span>
    邮箱:<input type="text" id="email" name="email">
    <span id="s3"></span>
    <button id="submit">提交</button>
    <!-- <script src="./validator.js"></script> -->
    <script>
        //用户名长度不能大于3 不能为空
        //密码长度不能小于6 不能为空
        // var flag = true; // 默认能发送
        // submit.onclick = function(){
        //     s1.innerText = '';
        //     s2.innerText = '';
        //     if(userDom.value == ''){
        //         flag = false;
        //         s1.innerText = '用户名不能为空';
        //     } else if( userDom.value.length >3){
        //         flag = false;
        //         s1.innerText = '用户名长度不能大于3';
        //     }
        //     if(psDom.value == ''){
        //         flag = false;
        //         s2.innerText = '密码不能为空';
        //     } else if(psDom.value.length < 6){
        //         flag = false;
        //         s2.innerText = '密码长度不能小于6';
        //     }
        //     if(flag){
        //         request();
        //     }
        // }
        // function request(){

        // }

        function Request() {
            console.log('send')
        }
        submit.onclick = function () {
            ProxyRequest();
        }
        // 验证
        // add 添加验证规则 
        //(dom,[{strategy:'isNonEmpty',errorMsg:'用户名不能为空'},{strategy:'maxLength:4',errorMsg:'用户名长度不能超过4'}])
        // start 开始校验并返回真正校验结果
        // extend 可以扩展方法 {isMail:function(){}}
        function Validator() {
            this.cache = [];
            this.warnText = [];
        }
        Validator.prototype.strategies = {
            isNonEmpty: function (value, errorMsg) {
                if (value == '') {
                    return errorMsg;
                }
                return true;
            },
            maxLength: function (value, length, errorMsg) {
                if (value != '' && value.length > length) {
                    return errorMsg;
                }
                return true;
            },
            minLength: function (value, length, errorMsg) {
                if (value != '' && value.length < length) {
                    return errorMsg;
                }
                return true;
            }
        }
        Validator.prototype.add = function (dom, showDom, strategyArr) {
            strategyArr.forEach((element, index) => {
                var self = this;
                this.warnText.push(showDom);
                this.cache.push(function () {
                    //[isNonEmpty] ['maxLength','4']
                    var arr = element.strategy.split(':');
                    //[] ['4']
                    // 'isNonEmpty' 'maxLength'
                    var type = arr.shift()
                    //[dom.value] [dom.value,'4']
                    arr.unshift(dom.value);
                    arr.push(element.errorMsg);
                    //value,errorMsg  value,length,errorMsg
                    var msg = self.strategies[type].apply(self, arr);
                    if (msg != true) {
                        showDom.innerText = msg;
                    }
                    return msg;
                });

            });
        }
        Validator.prototype.start = function () {
            var flag = true;
            this.warnText.forEach(function (ele) {
                ele.innerText = '';
            })
            this.cache.forEach(function (ele, index) {
                if (ele() !== true) {
                    flag = false;
                }
            });
            return flag;
        }
        Validator.prototype.extend = function (config) {
            for (var prop in config) {
                //在原型上面加方法
                Validator.prototype.strategies[prop] = config[prop];
            }
        }
        var validator = new Validator();
        validator.extend({
            isEmail: function (value, errorMsg) {
                if (value !== '' && value.indexOf('@') === -1) {
                    return errorMsg;
                }
                return true;
            },
            isPhone: function (value, errorMsg) {
                if (value !== '' && value.length !== 11) {
                    return errorMsg;
                }
                return true;
            }

        })


        var ProxyRequest = (function () {
            // 1.校验内容dom 2.错误信息显示dom 3.校验规则
            validator.add(userDom, s1, [{
                //策略
                strategy: 'isNonEmpty',
                errorMsg: '用户名不能为空'
            }, {
                strategy: 'maxLength:4',
                errorMsg: '用户名长度不能超过4'
            }]);
            validator.add(psDom, s2, [{
                strategy: 'isNonEmpty',
                errorMsg: '密码不能为空'
            }, {
                strategy: 'minLength:6',
                errorMsg: '密码长度不能小于6'
            }]);
            validator.add(email, s3, [{
                strategy: 'isNonEmpty',
                errorMsg: '邮箱不能为空'
            }, {
                strategy: 'isEmail',
                errorMsg: '邮箱格式不对'
            }])
            return function () {
                if (validator.start() == true) {
                    Request();
                }
            }
        })()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值