[Patrones de diseño simples] 7. Ejemplo de patrón proxy y Python (comienzo del patrón estructural)

presentación profesional:

Proporciona un proxy para que otros objetos controlen el acceso a este objeto. En este momento, el objeto de acceso no es adecuado o no puede referirse directamente al objeto de destino, y el objeto proxy actúa como intermediario entre el objeto de acceso y el objeto de destino.

Introducción popular: 

En algunos casos, los usuarios (clientes) no pueden acceder directamente a un objeto, lo que puede deberse a las siguientes razones:

       1. Es necesario proteger este objeto para que no lo cambien algunos clientes/consumidores.

       2. Quiere ampliar o eliminar algunas funciones de este objeto, pero no puede/es inconveniente modificar directamente este objeto

       3. El costo del acceso directo a los objetos es demasiado alto, y se requieren objetos intermedios para acceder a ellos en nombre de ellos y luego proporcionarlos a los usuarios.

Proporcione un intermediario (agente) para que lo use el cliente, y el intermediario accede directamente al objeto y brinda servicios al cliente.

 Ejemplo: El departamento de I+D debe proporcionar al departamento de desarrollo de datos una interfaz para consultar los datos de la base de datos. El departamento de desarrollo de datos solo necesita el permiso para consultar (seleccionar) y no se requieren otros permisos. En este momento, el departamento de I+D suele escribir una interfaz basada en el protocolo http para TI, si la autoridad está restringida en la interfaz, entonces esta interfaz puede llamarse agente de acceso a la base de datos (también se puede usar middleware).

Hay 3 roles en el modo proxy:

  • tema abstracto
  • tema real
  • interino

Desventajas del modo proxy:

         1. Se añade una capa entre visitante y visitante, que reduce en cierta medida la velocidad de acceso

         2. Mayor complejidad del sistema.

El siguiente código resuelve el ejemplo anterior (en forma de clase):

código:

# 代理模式

import abc, six


# step-1: 定义抽象主题
@six.add_metaclass(abc.ABCMeta)
class AbstractDBAccessSubject:
    @abc.abstractmethod
    def select(self, sql): pass

    @abc.abstractmethod
    def delete(self, sql): pass

    @abc.abstractmethod
    def insert(self, sql): pass

    @abc.abstractmethod
    def update(self, sql): pass


# step-2: 定义具体主题
class DBAccesSubject(AbstractDBAccessSubject):
    def select(self, sql):
        return self.execute_sql(sql, 'select')

    def delete(self, sql):
        return self.execute_sql(sql, 'delete')

    def insert(self, sql):
        return self.execute_sql(sql, 'insert')

    def update(self, sql):
        return self.execute_sql(sql, 'update')

    def execute_sql(self, sql, op):
        return 'real_data', sql, op


# step-3: 定义代理(继承具体主题)
class DBAccesProxy(DBAccesSubject):
    def __init__(self, user, passwd):
        account_check = {
            'user1': {
                'passwd': 123, 'permission': ['select']
            }
        }
        self.user = ''
        self.permission = []
        self.logged = False
        u = account_check.get(user, {})
        if u.get('passwd') and u.get('passwd') == passwd:
            self.user = user
            self.permission = u.get('permission')
            self.logged = True
            return
        print('Invalid user and passwd!')

    def select(self, sql):
        if 'select' not in self.permission:
            print('Insufficient authority!')
            return
        return super(DBAccesProxy, self).select(sql)

    def delete(self, sql):
        if 'delete' not in self.permission:
            print('Insufficient authority!')
            return
        return super(DBAccesProxy, self).delete(sql)

    def insert(self, sql):
        if 'insert' not in self.permission:
            print('Insufficient authority!')
            return
        return super(DBAccesProxy, self).insert(sql)

    def update(self, sql):
        if 'update' not in self.permission:
            print('Insufficient authority!')
            return
        return super(DBAccesProxy, self).update(sql)


if __name__ == '__main__':
    db_access_proxy = DBAccesProxy('xxx', 123)  # Invalid user and passwd!
    # if not db_access_proxy.logged:
    #     exit()
    db_access_proxy = DBAccesProxy('user1', 123)
    s = db_access_proxy.select('select * from x')
    print(s)  # ('real_data', 'select * from x', 'select')
    db_access_proxy.update('update x set a=1')  # Insufficient authority!

Explicación : se puede ver en el código que, sobre la base de proporcionar acceso a la base de datos, la clase de proxy también proporciona funciones de autenticación de identidad y control de autoridad, realizando una extensión no invasiva.

Según el código, también podemos ver dos desventajas del modo proxy:

  1. Hay una correspondencia uno a uno entre el tema real y el tema proxy, y la adición del tema real también aumenta el proxy.
  2. Agentes de Diseño Anteriormente tenían que existir temas reales de antemano, no muy flexibles. (Usar el modo de proxy dinámico puede resolver los problemas anteriores)

 

Observaciones: Para conocer el uso básico de las bibliotecas abc y six, consulte la introducción al final del artículo  Simple Factory Pattern & Python Example  , :)

Bienvenido a dejar un mensaje ~

 

 

Artículo de referencia:

http://c.biancheng.net/view/1354.html

Supongo que te gusta

Origin blog.csdn.net/sc_lilei/article/details/103365858
Recomendado
Clasificación