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()
View Code

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)
View Code

 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)
viptype
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)
UserType
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
User

    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:
        """
IUseRepository

    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
UserService

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)
UserService

   
服务层:
    1、调用业务处理(业务中的XX)

 

8、jquery 操作cookie  cookie中文问题

根据RFC 2109中的规定,在Cookie中只能包含ASCII的编码,难怪总是出现错误或者乱码,知道问题的所在就好解决拉,转换一下编码试试:

 

 

 

  

posted @ 2016-09-07 10:33  若时光搁浅  阅读(364)  评论(0)    收藏  举报