zoukankan      html  css  js  c++  java
  • 中介者模式+装饰器模式

          中介者模式的定义:通过⼀个中介者对象,其他所有的相关对象都通过该中介者对象来通信,⽽不是相互引⽤,当其中的⼀个对象发⽣改变时,只需要通知中介者对象即可。通过中介者模式可以解除对象与对象之间的紧耦合关系。
    例如:现实⽣活中,航线上的⻜机只需要和机场的塔台通信就能确定航线和⻜⾏状态,⽽不需要和所有⻜机通信。同时塔台作为中介者,知道每架⻜机的⻜⾏状态,所以可以安排所有⻜机的起降和航线安排。
    中介者模式适⽤的场景:例如购物⻋需求,存在商品选择表单、颜⾊选择表单、购买数量表单等等,都会触发change事件,那么可以通过中介者来转发处理这些事件,实现各个事件间的解耦,仅仅维护中介者对象即可。redux,vuex 都属于中介者模式的实际应⽤,我们把共享的数据,抽离成⼀个单独的store, 每个都通过store这个中介来操作对象
    ⽬的就是减少耦合。
           装饰者模式的定义:在不改变对象⾃身的基础上,在程序运⾏期间给对象动态地添加⽅法。常⻅应⽤,react的⾼阶组件, 或者react-redux中的@connect 或者⾃⼰定义⼀些⾼阶组件
     
           import React from 'react'
           const withLog = Component=>{
          // 类组件
         class NewComponent extends React.Component{
         componentWillMount(){
         console.time(`CompoentRender`)
         console.log(`准备完毕了`)
         }
         render(){
         return <Component {...this.props}></Component>
         }
         
          componentDidMount(){
               console.timeEnd(`CompoentRender`)
               console.log(`渲染完毕了`)
         }
         }
         return NewComponent
          }
         export {withLog}
         @withLog
         class XX
    export const connect = (mapStateToProps = state => state, mapDispatchToProps =
    {}) => (WrapComponent) => {
    return class ConnectComponent extends React.Component {
    static contextTypes = {
    store: PropTypes.object
    }
    constructor(props, context) {
    super(props, context)
    this.state = {
    props: {}
    }
    }
    componentDidMount() {
    const { store } = this.context
    // 当前状态 update 后, 放⼊监听器中, ⽤于下⼀次的更新(每次 dispatch 后会执⾏
    subscribe 中的所有函数)
    store.subscribe(() => this.update())
    this.update()
    }
    update() {
    const { store } = this.context
    const stateProps = mapStateToProps(store.getState())
    const dispatchProps = bindActionCreators(mapDispatchToProps,
    store.dispatch)
    this.setState({
    props: {
    ...this.state.props,
    ...stateProps,
    ...dispatchProps
    }
    })
    }
    render() {
    return <WrapComponent {...this.state.props}></WrapComponent>
    }
    }
    }
    假设我们在编写⼀个⻜机⼤战的游戏,随着经验值的增加,我们操作的⻜机对象可以升级成更厉害的⻜机,⼀开始这些⻜机只能发射普通的⼦弹,升到第⼆级时可以发射导弹,升到第三级时可以发射原⼦弹。
             
    Function.prototype.before = function( beforefn ){
    var __self = this; // 保存原函数的引⽤
    return function(){ // 返回包含了原函数和新函数的"代理"函数
    beforefn.apply( this, arguments ); // 执⾏新函数,且保证 this 不被劫持,新函
    数接受的参数 // 也会被原封不动地传⼊原函数,新函数在原函数之前执⾏
    return __self.apply( this, arguments ); // 执⾏原函数并返回原函数的执⾏结
    果, // 并且保证 this 不被劫持
    } }
    Function.prototype.after = function( afterfn ){
    var __self = this;
    return function(){
    var ret = __self.apply( this, arguments );
    afterfn.apply( this, arguments );
    return ret;
    }
    };
                    ⽐如⻚⾯中有⼀个登录 button,点击这个 button 会弹出登录浮层,与此同时要进⾏数据上报, 来统计有多少⽤户点击了这个登录 button
     
    var showLogin = function(){
    console.log( '打开登录浮层' );
    log( this.getAttribute( 'tag' ) );
    }
    var log = function( tag ){
    console.log( '上报标签为: ' + tag );
    (new Image).src = 'http:// xxx.com/report?tag=' + tag;
    }
    document.getElementById( 'button' ).onclick = showLogin;
    使⽤装饰器
    var showLogin = function(){
    console.log( '打开登录浮层' );
    }
    var log = function(){
    console.log( '上报标签为: ' + this.getAttribute( 'tag' ) );
    }
    showLogin = showLogin.after( log ); // 打开登录浮层之后上报数据
    document.getElementById( 'button' ).onclick = showLogin;
    装饰者模式和代理模式的结构看起来⾮常相像,这两种模式都描述了怎样为对象提供 ⼀定程度上的间接
    引⽤,它们的实现部分都保留了对另外⼀个对象的引⽤,并且向那个对象发送 请求。 代理模式和装饰
    者模式最重要的区别在于它们的意图和设计⽬的。代理模式的⽬的是,当直接访问本体不⽅便或者不符
    合需要时,为这个本体提供⼀个替代者。本体定义了关键功能,⽽代理提供或拒绝对它的访问,或者在
    访问本体之前做⼀些额外的事情。装饰者模式的作⽤就是为对 象动态加⼊⾏为。
    其实Vue中的v-input,v-checkbox也可以认为是装饰器模式, 对原⽣的input和checkbox做⼀层装饰
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     

         

  • 相关阅读:
    bzoj 3438: 小M的作物
    bzoj 4445 [SCOI2015] 小凸想跑步
    hdu 4899 Hero meet devil
    hdu 4898 The Revenge of the Princess’ Knight
    【NOIP1999】拦截导弹
    【OpenJudge】2991:2011 题解
    【cqbzoj】1785:残缺棋盘上放车的方案数 --状压dp --输入毁一生
    【cqbzoj】:1330 Prime DP(Ahio2001 质数和分解)
    【Openjudge:Noi】7891:一元三次方程求解 c++
    【USACO FEB 2010 SILVER】吃巧克力(Chocolate Eating)
  • 原文地址:https://www.cnblogs.com/zhouyideboke/p/13426571.html
Copyright © 2011-2022 走看看