zoukankan      html  css  js  c++  java
  • 组合与依赖注入

    组合的场景出现在两个类需要协同工作的时候,这个时候需要考虑到解耦,不能让两个类之间有直接的关系,因为有可能有功能相似的类作用于第三个类里面

    例如两个处理数据库的类功能相等,但是分为两个,如果Userinfo里面写死,就不能用第三个类了

    实现原理:把一个对象当做参数传进来,而不是在该类的内部实例化,这样降低了类和类之间的耦合。

    class SqlHelper:
        def get_one_data(self):
            pass
        def get_many_data(self):
            pass
        def get_all_data(self):
            pass
    class MysqlHelper:
        def get_one_data(self):
            pass
        def get_many_data(self):
            pass
        def get_all_data(self):
            pass
    
    class UserInfo:
        def __init__(self,helper):
            #self.sql = SqlHelper()
            self.sql = helper
    
        def login(self):
            #数据库操作
            self.sql.get_one_data()
    
        def user_list(self):
            self.sql.get_all_data()
    
    h = SqlHelper()
    obj = UserInfo(h)
    obj.login()
    

      

    另一种场景:

    如果SQL函数还依赖一个类,即使用SQL类的时候同样的需要初始化一个类,然后把这个类当做参数传进来。

    class foo:
        def f1(self):
            pass
        def f2(self):
            pass
    
    class SqlHelper:
        def __init__(self,f):
            self.foo = f
        def get_one_data(self):
            self.foo.f1()
            pass
        def get_many_data(self):
            pass
        def get_all_data(self):
            pass
    class MysqlHelper:
        def __init__(self,f):
            self.foo = f
        def get_one_data(self):
            pass
        def get_many_data(self):
            pass
        def get_all_data(self):
            pass
    
    class UserInfo:
        def __init__(self,helper):
            #self.sql = SqlHelper()
            self.sql = helper
    
        def login(self):
            #数据库操作
            self.sql.get_one_data()
    
        def user_list(self):
            self.sql.get_all_data()
    
    f = foo()
    h = SqlHelper(f)
    obj = UserInfo(h)
    obj.login()
    

      

    这样会出现的问题,架构越来越大,层级越来越盛,有没有一种方法可以省略掉之前的继承

    使用组合依赖的方式实现,在类初始化之前在__new__方法之后把需要传入的参数加进来,这个类和对应的参数又放在

    Mapper类里面来管理,细节如下:

    class Mapper:
        __mapper_relation = {
            #'类':参数
        }
        @staticmethod
        def register(cls,value):   #注册类和参数
            Mapper.__mapper_relation[cls] = value
    
        @staticmethod
        def exist(cls):
            if cls in Mapper.__mapper_relation:
                return True
            return False
    
        @staticmethod
        def value(cls):
            return  Mapper.__mapper_relation[cls]
    
    class MyType(type):
        """
        由于type类是C++实现的,所以创建一个类让它继承type,然后重写type的__call__方法
        后面创建的类再显式的指定需要继承的是MyType
        """
        def __call__(cls,*args,**kwargs):
            obj = cls.__new__(cls,*args,**kwargs)
            arg_list = list(args)
            if Mapper.exist(cls):
                value = Mapper.value(cls)
                arg_list.append(value)
            obj.__init__(*arg_list,**kwargs)
            return obj
    
    class Foo():
        def f1(self):
            pass
        def f2(self):
            pass
    
    class SqlHelper(metaclass=MyType):
        def __init__(self,f):
            self.foo = f
        def get_one_data(self):
            self.foo.f1()
            pass
        def get_many_data(self):
            pass
        def get_all_data(self):
            pass
    
    class MysqlHelper(metaclass=MyType):
        def __init__(self,f):
            self.foo = f
        def get_one_data(self):
            pass
        def get_many_data(self):
            pass
        def get_all_data(self):
            pass
    
    class UserInfo(metaclass=MyType):
        def __init__(self,helper):
            #self.sql = SqlHelper()
            self.sql = helper
    
        def login(self):
            #数据库操作
            self.sql.get_one_data()
    
        def user_list(self):
            self.sql.get_all_data()
    
    # f = foo()
    # h = SqlHelper(f)
    # obj = UserInfo(h)
    # obj.login()
    #创建SqlHelper之前又要创建Foo对象
    Mapper.register(SqlHelper,Foo())
    #创建UserInfo之前需要创建SqlHelper或MysqlHelper对象使用Mapper注册
    Mapper.register(UserInfo,SqlHelper())
    
    #接下来实例化UesrInfo不需要传任何参数
    obj= UserInfo()
    print(obj.sql.foo)
    

      

  • 相关阅读:
    欠拟合与过拟合概念和局部加权回归
    ActionEvent之TextField
    事件模型的介绍与Button的ActionListener
    布局管理器
    GUI初步和frame&panel
    生产者消费者问题
    线程同步
    [BZOJ 1407] Savage
    [BZOJ 1145] 图腾totem
    [BZOJ 1150] 数据备份
  • 原文地址:https://www.cnblogs.com/qiangayz/p/9352253.html
Copyright © 2011-2022 走看看