jd 商城大项目(一)——接口、依赖注入
知识补充:
1、接口
(1)接口分两类,一类是暴露API 通过url访问返回数据
(2)数据类型,python不存在
(3)抽象类+抽象方法 组成python的接口
(4)类只要继承(实现)了接口,那么类就会受约束
以前笔记:
接口起约束作用
抽象类如果没有抽象方法跟普通的类一样
如果抽象类的普通方法跟其他类一样 如果抽象类有抽象方法,其他的类又继承了抽象方法,则那个其他类必须写抽象方法名字一样的方法
classF(metaclass=abc.ABCMeta) 抽象类
@abc.abstractmethod 抽象方法
抽象类+抽象抽象方法
抽象类:技能继承又能约束
抽象方法:约束子类必须有这种方法
from abc import ABCMeta from abc import abstractmethod class Father(metaclass=ABCMeta): @abstractmethod def f1(self):pass @abstractmethod def f2(self):pass class F1(Father): def f1(self): pass def f2(self): pass def f3(self): pass obj = F1()
2、依赖注入
(1)一个类的创建流程
类都是type创建的
遇到class Foo 执行type的__init__方法
type 的__init__执行了什么不知道,
执行type的__call__方法
执行type的__new__方法
执行Foo类的__init__方法
(2)可以自己创建一个MyType 继承type 子类通过继承MyTpe创建类,在Mytype里面自定义__init__ 然后传值,
class MyType(type): def __call__(cls, *args, **kwargs): obj = cls.__new__(cls, *args, **kwargs) print("============================") obj.__init__(*args, **kwargs) return obj class Foo(metaclass=MyType): def __init__(self,name): print("--------------------") self.name = name def f1(self): print(self.name) obj = Foo(123) print(obj) print(obj.name)
(3)依赖注入需要通过一个其他类来协助实现
(1)这个类要有一个集合来存放所有的类名和需要穿的值
(2)有增删查改的静态方法
(4)依赖注入实现的代码
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): 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(metaclass=MyType): def __init__(self,name): self.name =name def f1(self): print(self.name) class Bar(metaclass=MyType): def __init__(self,name): self.name =name def f1(self): print(self.name) Mapper.register(Foo,"6666") Mapper.register(Bar,"9999") f=Foo() print(f.name) b=Bar() print(b.name)
#!/usr/bin/env python # -*- coding:utf-8 -*- # class MyType(type): # def __call__(cls, *args, **kwargs): # obj = cls.__new__(cls, *args, **kwargs) # print(cls) # if cls == Foo: # obj.__init__(123) # if cls ==foo2: # obj.__init__(Foo) # if cls == foo3: # obj.__init__(foo2) # return obj # # class Foo(metaclass=MyType): # def __init__(self,name): # self.name = name # # def f1(self): # print(self.name) # # class foo2(metaclass=MyType): # def __init__(self,arg): # self.Foo=arg # # def f2(self): # print(222222222) # self.Foo().f1() # # class foo3(metaclass=MyType): # def __init__(self,arg2): # self.foo2 = arg2 # # def f3(self): # self.foo2().f2() # # # # obj = foo3() # obj.f3() # print(obj) # print(obj.name) # 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): # 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(metaclass=MyType): # def __init__(self,name): # self.name =name # # def f1(self): # print(self.name) # # class Bar(metaclass=MyType): # def __init__(self,name): # self.name =name # # def f1(self): # print(self.name) # # Mapper.register(Foo,"6666") # Mapper.register(Bar,"9999") # # f=Foo() # print(f.name) # b=Bar() # print(b.name) #!/usr/bin/env python # -*- coding:utf-8 -*- 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): 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 Test: def __init__(self): pass class Foo(metaclass=MyType): def __init__(self, t): self.t = t def f1(self): print(self.name) class Bar(metaclass=MyType): def __init__(self, f): self.f = f def f1(self): print(self.name) Mapper.register(Foo,Test()) Mapper.register(Bar,Foo()) b = Bar() print(b.f)
3、程序设计原则
SOLIP设计原则
(1)单一责任原则(SRP)
一个对象对只应该为一个元素负责
所有数据库操作放在一个类中
(2)开放封闭原则(OCP)
对扩展开放,修改封闭
setter 装饰器
(3)里氏替换原则(LSP)
可以使用任何派生类替换基类
(4)接口分离原则(ISP)
对于接口进行分类避免一个接口的方法过多
(5)依赖倒置原则(DIP)
隔离关系,使用接口或抽象类代指
(6)依赖注入(DI)和控制反转原则(ICO)
使用钩子再原来执行流程中注入其他对象
4、企业应用设计:
数据访问层
业务处理层
表示层
(1)数据访问层
a. 数据访问策略
- DAO,通常一个表一个Dao类
- Repository,更高抽象层次上处理业务实体聚合
b. 数据访问模式
- unin of work(工作单元)
三个列表 统一做操作 打开数据库提交
- Query Object(查询对象),格式化规则,自动创建SQL
定义一套规则 转成sql语句
2、业务处理层
a. 业务逻辑组织
- Transcation Script模式(事务脚本模式) 一个功能一个函数
- Active Record(活动记录) 业务上创建一个了类,业务了里的类和数据库表里的字段一样
- Domain Model(领域模型) 属性+行为
- Anemic Domain Model(反模式) 属性 不能有行为
类似于领域模型,但是反模式的领域对象中不包含任何行为,行为位于模型之外,让领域作为简单的数据传输类,领域服务更加巨细
- 领域驱动设计(Domain Driven Design)利用领域模型来解决事情
领域驱动设计,一种流行的利用Domain Model 模式的设计方法学,简而言之DDD就是一组帮助人们构建能够反应业务并满足业务需求的应用程序的模式和原则。
b. 设计模式
- 工厂模式
- 策略模式
5、组合解耦
class SqlHelper: def fetch_one(self): pass def fetch_all(self): pass class UserInfo: def __init__(self, helper): # self.s = SqlHelper() self.s = helper def login(self): # 数据库操作 self.s .fetch_one() def logout(self): # 数据库操作 self.s .fetch_one() def user_list(self): # 数据库操作 self.s .fetch_all() h = SqlHelper() obj = UserInfo(h) obj.login()
6、选择类型
1、小 MVC 2、中 三层架构 工具 数据访问层 Dao/Repository/Dal -m 业务处理 Service/model/Bll UI Web - v - c 3、企业组织 数据访问层 Dao: 数据库表 <-> Dao类 Repository: 业务处理层 服务层 表示层(UI)
7、Repository(数据访问):
1、数据访问 - UserRepository
利用建模 将数据格式化 存在Model 里面
Model(业务处理):
1、建模(领域模型) -- 3个类
class VipType: VIP_TYPE = ( {'nid': 1, 'caption': '铜牌'}, {'nid': 2, 'caption': '银牌'}, {'nid': 3, 'caption': '金牌'}, {'nid': 4, 'caption': '铂金'}, ) def __init__(self, nid): self.nid = nid def get_caption(self): caption = None for item in VipType.VIP_TYPE: if item['nid'] == self.nid: caption = item['caption'] break return caption caption = property(get_caption)
class UserType: USER_TYPE = ( {'nid': 1, 'caption': '用户'}, {'nid': 2, 'caption': '商户'}, {'nid': 3, 'caption': '管理员'}, ) def __init__(self, nid): self.nid = nid def get_caption(self): caption = None for item in UserType.USER_TYPE: if item['nid'] == self.nid: caption = item['caption'] break return caption caption = property(get_caption)
class User: """领域模型""" def __init__(self, nid, username, email, last_login, user_type, vip_type): self.nid = nid self.username = username self.email = email self.last_login = last_login self.user_type = user_type self.vip_type = vip_type
2、约束:(接口) -- IUseRepository
class IUseRepository(metaclass=abc.ABCMeta): """ 用户信息仓库接口 """ @abc.abstractmethod def fetch_one_by_user_pwd(self, username, password): """ 根据用户名密码获取模型对象 :param username: 主键ID :param password: 主键ID :return: """ @abc.abstractmethod def fetch_one_by_email_pwd(self, email, password): """ 根据邮箱密码获取模型对象 :param email: 主键ID :param password: 主键ID :return: """ @abc.abstractmethod def update_last_login_by_nid(self,nid,current_date): """ 根据ID更新最新登陆时间 :param nid: :return: """
3、协调 领域模型 和 数据访问处理业务(业务中的XX),模型 结果给【服务层】
去Model去执行Repository里面的方法,去数据库操作
class UserService: def __init__(self, user_repository): self.userRepository = user_repository def check_login(self, username=None, email=None, password=None): if username: user_model = self.userRepository.fetch_one_by_user_pwd(username, password) else: user_model = self.userRepository.fetch_one_by_email_pwd(email, password) if user_model: current_date = datetime.datetime.now() self.userRepository.update_last_login_by_nid(user_model.nid, current_date) return user_model
Server里面的
请求来了 告诉调用model里面的方法,
class UserService: def __init__(self, model_user_service): self.modelUserService = model_user_service def check_login(self, user_request): response = UserResponse() try: model = self.modelUserService.check_login(user_request.username, user_request.email, user_request.password) if not model: raise Exception('用户名或密码错误') else: model_view = UserModelView(nid=model['nid'], username=model['usename'], email=model['email'], last_login=model['last_login'], user_type_id=model['user_type'].nid, user_type_caption=model['user_type'].caption, vip_type_id=model['vip_type'].nid, vip_type_caption=model['vip_type'].caption,) response.modelView = model_view except Exception as e: response.status = False response.message = str(e)
服务层:
1、调用业务处理(业务中的XX)
8、jquery 操作cookie cookie中文问题
根据RFC 2109中的规定,在Cookie中只能包含ASCII的编码,难怪总是出现错误或者乱码,知道问题的所在就好解决拉,转换一下编码试试:

浙公网安备 33010602011771号