zoukankan      html  css  js  c++  java
  • 设计模式(四):代理模式

      Head Fisrt设计模式上面有一句话:代理模式要做的:控制和管理访问。代理类似于明星的经纪人,可以处理来访的需求,但不影响明星本人的行为。

      下面的例子,TV是对电视的操作,有channel表示当前的频道,power表示电视电源开关。通过proxy代理,可以记录曾经的操作,如打开的次数,转频道的次数等。

    import random
    import unittest
    
    
    class TV(object):
        """docstring for TV"""
        def __init__(self, brand):
            self._brand = brand
            self._channel = None
            self._power = None
    
        @property 
        def brand( self ):
            return self._brand
    
        @property
        def channel( self ):
            return self._channel
    
        @channel.setter
        def channel( self, value ):
            self._channel = value
    
        
    
        def power( self ):
            if "on" == self._power:
                self._power = "off"
            else:
                self._power = "on"
    
        def showPower( self ):
            return self._power
    
    
    
    
    class TestTvClass( unittest.TestCase ):
        """docstring for TestBasicClass"""
        
        def setUp( self ):
            self._tv = TV( "Apple" )
    
        def test_tv_class_has_attribute( self ):
            self.assertTrue( hasattr( self._tv, 'brand' ) )
            self.assertTrue( hasattr( self._tv, 'channel' ) )
            self.assertTrue( hasattr( self._tv, 'power' ) )
            self.assertTrue( hasattr( self._tv, 'showPower' ) )
    
        def test_tv_initiate_state( self ):
            self.assertEqual( 'Apple', self._tv.brand )
            self.assertEqual( None, self._tv.showPower() )
            self.assertEqual( None, self._tv.channel )
    
        def test_turn_on_tv_to_channel_10( self ):
            self._tv.power()
            self._tv.channel = 10
    
            self.assertEqual( 'on', self._tv.showPower() )
            self.assertEqual( 10, self._tv.channel )
    
        def test_turn_off_tv( self ):
            self._tv.power()
            self._tv.channel = 10
            self._tv.power()
    
            self.assertEqual( 'off', self._tv.showPower() )
            self.assertEqual( 10, self._tv.channel )
    
        def tearDown( self ):
            pass
    
    
    class Proxy(object):
        """docstring for Proxy"""
        def __init__(self, tv_object):
    
            self._records = []
            self._obj = tv_object
    
        def __setattr__( self, attrname, value ):
            if '_' == attrname[0]:
                object.__setattr__( self, attrname, value )
            else:
                self._records.append( attrname )
                self._obj.__setattr__( attrname, value ) 
    
        def __getattr__( self, attrname ):
            if '_' == attrname[0]:
                return object.__getattribute__( self, attrname )
            else:
                self._records.append( attrname )
                return self._obj.__getattribute__( attrname )
    
        def showRecord( self ):
            return self._records
    
        def number_of_operate( self, attrname ):
            return self._records.count( attrname )
            
    
    class TestProxy( unittest.TestCase ):
        """docstring for TestProxy"""
        def setUp( self ):
            self._tv = Proxy( TV( "Apple" ) )
    
        def test_proxy_has_attribute( self ):
            self.assertTrue( hasattr( self._tv, 'showRecord' ) )
    
        def test_handle_property_from_proxy_to_tv( self ):
            self._tv.power()
            self._tv.channel = 10
            self.assertEqual( 10, self._tv.channel )
            self.assertEqual( 'on', self._tv.showPower() )
    
        def test_get_operate_tv_record( self ):
            self._tv.power()
            self._tv.channel = 20
    
            self.assertEqual( ['power', 'channel'], self._tv.showRecord() )
            self.assertEqual( 20, self._tv.channel )
    
        def test_get_operate_number( self ):
            self._tv.power()
            self._tv.channel = 10
    
            self.assertEqual( 1, self._tv.number_of_operate( 'power' ) )
            self.assertEqual( 1, self._tv.number_of_operate( 'channel' ) )
    
    
    
    if __name__ == '__main__':
        unittest.main()

       下面是C++实现的一个虚代理的例子:如果直接打开一个图片,所花费的代价会比较大,那么,只要设定一个代理,用户先快速打开代理。然后等需要的时候再打开真正的图片。

    View Code
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Image
    {
    public:
        Image( string name ) : m_imageName( name ){}
        virtual ~Image(){}
        virtual void Show(){}
    
    protected:
        string m_imageName;
        /* data */
    };
    
    class BigImage : public Image
    {
    public:
        BigImage( string name ) : Image( name ){}
        ~BigImage(){}
        void Show() 
        { 
            cout << "Show big image." << m_imageName << endl; 
        }
    
        /* data */
    };
    
    class BigImageProxy : public Image
    {
    public:
        BigImageProxy( string name ) : Image( name ), m_bigImage( 0 ) {}
        ~BigImageProxy(){ delete m_bigImage; }
    
        void Show()
        {
            if ( NULL == m_bigImage )
            {
                m_bigImage = new BigImage( m_imageName );
            }
            m_bigImage->Show();
        }
    
        /* data */
    private:
        BigImage *m_bigImage;
    };
    
    
    
    
    int main()
    {
        Image *image = new BigImageProxy( "proxy.jpg" );
        image->Show();
        delete image;
        return 0;
    }
  • 相关阅读:
    C++继承与派生的概念、什么是继承和派生
    为什么要用重载(学习笔记)
    C++ 为什么要用覆盖(学习笔记)
    做一个爱分享的人技术牛人博客
    okhttp head()请求
    android 8.0 前台服务问题
    android 配置 kotlin 使用jdk1.8编译
    java 获取apk包的版本号、包路径。权限信息
    vue 自定义input控件 v-model 绑定数据问题
    android ViewModel 列表数据获取条数
  • 原文地址:https://www.cnblogs.com/bracken/p/3006212.html
Copyright © 2011-2022 走看看