【设计模式

2023-11-17

every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

  1. 【设计模式 | 上】【创建型】
  2. 【设计模式 | 中】【行为型】
  3. 【设计模式 | 下】【行为型】
    1. 观察者模式
    2. 状态模式
    3. 策略模式
    4. 职责链模式
    5. 命令模式
    6. 访问模式
    7. 调停者模式
    8. 备忘录模式
    9. 迭代器模式
    10. 解释器模式
    11. 模板方法模式

1. 正文

1.3 行为型

1.3.1 观察者模式–Observer

 
'''
Observer
'''
# 观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式
# 当我们希望一个对象的状态发生变化,那么依赖与它的所有对象都能相应变化(获得通知),那么就可以用到Observer模式, 其中的这些依赖对象就是观察者的对象,那个要发生变化的对象就是所谓’观察者’
 
class ObserverBase(object):
    '''观察者基类''' #放哨者
 
    def __init__(self):
        self._observerd_list = [] #被通知对象
 
    def attach(self,observe_subject):
        '''
        添加要观察的对象
        :param observe_subject:
        :return:
        '''
        if observe_subject not in self._observerd_list:
            self._observerd_list.append(observe_subject)
            print("[%s]已经将[%s]加入观察队列..."%(self.name,observe_subject) )
    def detach(self,observe_subject):
        '''
        解除观察关系
        :param observe_subject:
        :return:
        '''
        try:
            self._observerd_list.remove(observe_subject)
            print("不再观察[%s]" %observe_subject)
        except ValueError:
            pass
 
    def notify(self):
        '''
        通知所有被观察者
        :return:
        '''
        for objserver in self._observerd_list:
            objserver.update(self)
 
 
class Observer(ObserverBase):
    '''观察者类'''
 
    def __init__(self,name):
        super(Observer,self).__init__()
        self.name = name
        self._msg = ''
 
    @property  #外部执行d.eat 去掉括号
    def msg(self):
        '''
        当前状况
        :return:
        '''
        return self._msg
 
    @msg.setter  #设置属性(一个方法变成一个静态的属性)
    def msg(self,content):
        self._msg = content
        self.notify()
#目前结论:一个方法变成一个静态的属性 (装饰了@property)
#通过另外一个相同名字的方法(装饰@msg.setter )进行修改该属性
#简单: d = Observer('xxx')
       #print(d.msg)  结果:空
        #d.msg = 'xxx'
            # #这种形式调用该对象有装饰setter的方法,xxx作为形参
        #print(d.msg)  结果:xxx
 
 
class GCDViewer(object):
    '''
    共军被观察者
    '''
    def update(self,observer_subject):
        print("共军:收到[%s]消息[%s] "%(observer_subject.name,observer_subject.msg) )
 
class GMDViewer(object):
    '''
    国军被观察者
    '''
    def update(self,observer_subject):
        print("国军:收到[%s]消息[%s] "%(observer_subject.name,observer_subject.msg) )
 
 
if __name__ == "__main__":
    observer1 = Observer("共军放哨者")
    observer2 = Observer("国军放哨者")
 
    gongjun1 = GCDViewer()
    guojun1 = GMDViewer()
 
    observer1.attach(gongjun1)
    observer1.attach(guojun1)
 
 
    observer2.attach(guojun1)
 
    observer1.msg = "\033[32;1m敌人来了...\033[0m"
 
 
    observer2.msg ="\033[31;1m前方发现敌人,请紧急撤离,不要告诉共军\033[0m"

1.3.2 状态模式–State

'''
State
'''
 
class State(object):
    """Base state. This is to share functionality"""
 
    def scan(self):
        """Scan the dial to the next station"""
        self.pos += 1
        if self.pos == len(self.stations):
            self.pos = 0
        print("Scanning... Station is", self.stations[self.pos], self.name)
 
 
class AmState(State):
    def __init__(self, radio):
        self.radio = radio
        self.stations = ["1250", "1380", "1510"]
        self.pos = 0
        self.name = "AM"
 
    def toggle_amfm(self):
        print("Switching to FM")
        self.radio.state = self.radio.fmstate
 
class FmState(State):
    def __init__(self, radio):
        self.radio = radio
        self.stations = ["81.3", "89.1", "103.9"]
        self.pos = 0
        self.name = "FM"
 
    def toggle_amfm(self):
        print("Switching to AM")
        self.radio.state = self.radio.amstate
 
class Radio(object):
    """A radio.     It has a scan button, and an AM/FM toggle switch."""
    def __init__(self):
        """We have an AM state and an FM state"""
        self.amstate = AmState(self)
        self.fmstate = FmState(self)
        self.state = self.amstate
 
    def toggle_amfm(self):
        self.state.toggle_amfm()
 
    def scan(self):
        self.state.scan()
 
# Test our radio out
if __name__ == '__main__':
    radio = Radio()
    actions = [radio.scan] * 2 + [radio.toggle_amfm] + [radio.scan] * 2
    actions = actions * 2
 
    for action in actions:
        action()

1.3.3 策略模式–Strategy

'''
Strategy
'''
class TravelStrategy(object):
    '''
    出行策略
    '''
 
    def travelAlgorithm(self):
        pass
 
class AirplaneStrategy(TravelStrategy):
    def travelAlgorithm(self):
        print("坐飞机出行....")
 
class TrainStrategy(TravelStrategy):
    def travelAlgorithm(self):
        print("坐高铁出行....")
 
 
class CarStrategy(TravelStrategy):
    def travelAlgorithm(self):
        print("自驾出行....")
 
class BicycleStrategy(TravelStrategy):
    def travelAlgorithm(self):
        print("骑车出行....")
 
 
class TravelInterface(object):
    def __init__(self,travel_strategy):
        self.travel_strategy = travel_strategy
 
    def set_strategy(self,travel_strategy):
        self.travel_strategy = travel_strategy
    def travel(self):
        return self.travel_strategy.travelAlgorithm()
 
 
 
#坐飞机
travel = TravelInterface(AirplaneStrategy())
 
travel.travel()
 
#改开车
travel.set_strategy(CarStrategy())
travel.travel()

1.3.4 职责链模式–Chain of Responsibility

'''
Chain of Responsibility
'''
 
 
# 职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
# 适用场景:
# 1、有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定;
# 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
# 3、处理一个请求的对象集合应被动态指定。
 
class BaseHandler(object):
    '''处理基类'''
 
 
    def successor(self,successor): #next_handler
        #与下一个责任者关联
        self._successor = successor
 
class RequestHandlerL1(BaseHandler):
    '''第一级请求处理者'''
    name = "TeamLeader"
    def handle(self,request):
        if request < 500 :
            print("审批者[%s],请求金额[%s],审批结果[审批通过]"%(self.name,request))
        else:
            print("\033[31;1m[%s]无权审批,交给下一个审批者\033[0m" %self.name)
            self._successor.handle(request)
 
class RequestHandlerL2(BaseHandler):
    '''第二级请求处理者'''
    name = "DeptManager"
    def handle(self,request):
        if request < 5000 :
            print("审批者[%s],请求金额[%s],审批结果[审批通过]"%(self.name,request))
        else:
            print("\033[31;1m[%s]无权审批,交给下一个审批者\033[0m" %self.name)
            self._successor.handle(request)
 
class RequestHandlerL3(BaseHandler):
    '''第三级请求处理者'''
    name = "CEO"
    def handle(self,request):
        if request < 10000 :
            print("审批者[%s],请求金额[%s],审批结果[审批通过]"%(self.name,request))
        else:
            print("\033[31;1m[%s]要太多钱了,不批\033[0m"%self.name)
            #self._successor.handle(request)
 
class RequestAPI(object):
    h1 = RequestHandlerL1()
    h2 = RequestHandlerL2()
    h3 = RequestHandlerL3()
 
    h1.successor(h2)
    h2.successor(h3)
    def __init__(self,name,amount):
        self.name = name
        self.amount = amount
 
 
 
    def handle(self):
 
        '''统一请求接口'''
        self.h1.handle(self.amount)
 
 
if __name__ == "__main__":
    r1 = RequestAPI("Burgess",8000)
    r1.handle()
    print(r1.__dict__)

1.3.5 命令模式–Command

 
"""
Command
"""
import os
 
class MoveFileCommand(object):
    def __init__(self, src, dest):
        self.src = src
        self.dest = dest
 
    def execute(self):
        self()
 
    def __call__(self):
        print('renaming {} to {}'.format(self.src, self.dest))
        os.rename(self.src, self.dest)
 
    def undo(self):
        print('renaming {} to {}'.format(self.dest, self.src))
        os.rename(self.dest, self.src)
 
 
if __name__ == "__main__":
    command_stack = []
 
    # commands are just pushed into the command stack
    command_stack.append(MoveFileCommand('foo.txt', 'foo1.txt'))
    command_stack.append(MoveFileCommand('bar.txt', 'bar1.txt'))
 
    # they can be executed later on
    for cmd in command_stack:
        cmd.execute()
 
    # and can also be undone at will
    for cmd in reversed(command_stack):
        cmd.undo()

1.3.6 访问模式–Visitor

'''
Visitor
'''
 
 
class Node(object):
    pass
 
 
class A(Node):
    pass
 
 
class B(Node):
    pass
 
 
class C(A, B):
    pass
 
 
class Visitor(object):
    def visit(self, node, *args, **kwargs):
        meth = None
        for cls in node.__class__.__mro__:
            meth_name = 'visit_' + cls.__name__
            meth = getattr(self, meth_name, None)
            if meth:
                break
 
        if not meth:
            meth = self.generic_visit
        return meth(node, *args, **kwargs)
 
    def generic_visit(self, node, *args, **kwargs):
        print('generic_visit ' + node.__class__.__name__)
 
    def visit_B(self, node, *args, **kwargs):
        print('visit_B ' + node.__class__.__name__)
 
 
a = A()
b = B()
c = C()
visitor = Visitor()
visitor.visit(a)
visitor.visit(b)
visitor.visit(c)

1.3.7 调停者模式–Mediator

 
'''
Mediator
'''
 
import time
 
class TC:
    def __init__(self):
        self._tm = tm
        self._bProblem = 0
 
    def setup(self):
        print("Setting up the Test")
        time.sleep(1)
        self._tm.prepareReporting()
 
    def execute(self):
        if not self._bProblem:
            print("Executing the test")
            time.sleep(1)
        else:
            print("Problem in setup. Test not executed.")
 
    def tearDown(self):
        if not self._bProblem:
            print("Tearing down")
            time.sleep(1)
            self._tm.publishReport()
        else:
            print("Test not executed. No tear down required.")
 
    def setTM(self, TM):
        self._tm = tm
 
    def setProblem(self, value):
        self._bProblem = value
 
class Reporter:
    def __init__(self):
        self._tm = None
 
    def prepare(self):
        print("Reporter Class is preparing to report the results")
        time.sleep(1)
 
    def report(self):
        print("Reporting the results of Test")
        time.sleep(1)
 
    def setTM(self, TM):
        self._tm = tm
 
class DB:
    def __init__(self):
        self._tm = None
 
    def insert(self):
        print("Inserting the execution begin status in the Database")
        time.sleep(1)
        #Following code is to simulate a communication from DB to TC
        import random
        if random.randrange(1, 4) == 3:
            return -1
 
    def update(self):
        print("Updating the test results in Database")
        time.sleep(1)
 
    def setTM(self, TM):
        self._tm = tm
 
class TestManager:
    def __init__(self):
        self._reporter = None
        self._db = None
        self._tc = None
 
    def prepareReporting(self):
        rvalue = self._db.insert()
        if rvalue == -1:
            self._tc.setProblem(1)
            self._reporter.prepare()
 
    def setReporter(self, reporter):
        self._reporter = reporter
 
    def setDB(self, db):
        self._db = db
 
    def publishReport(self):
        self._db.update()
        rvalue = self._reporter.report()
 
    def setTC(self, tc):
        self._tc = tc
 
 
if __name__ == '__main__':
    reporter = Reporter()
    db = DB()
    tm = TestManager()
    tm.setReporter(reporter)
    tm.setDB(db)
    reporter.setTM(tm)
    db.setTM(tm)
    # For simplification we are looping on the same test.
    # Practically, it could be about various unique test classes and their
    # objects
    while (True):
        tc = TC()
        tc.setTM(tm)
        tm.setTC(tc)
        tc.setup()
        tc.execute()
        tc.tearDown()

1.3.8 备忘录模式–Memento

 
'''
Memento
'''
 
import copy
 
 
def Memento(obj, deep=False):
    state = (copy.copy, copy.deepcopy)[bool(deep)](obj.__dict__)
 
    def Restore():
        obj.__dict__.clear()
        obj.__dict__.update(state)
 
    return Restore
 
 
class Transaction:
    """A transaction guard. This is really just
      syntactic suggar arount a memento closure.
      """
    deep = False
 
    def __init__(self, *targets):
        self.targets = targets
        self.Commit()
 
    def Commit(self):
        self.states = [Memento(target, self.deep) for target in self.targets]
 
    def Rollback(self):
        for st in self.states:
            st()
 
 
class transactional(object):
    """Adds transactional semantics to methods. Methods decorated  with
    @transactional will rollback to entry state upon exceptions.
    """
 
    def __init__(self, method):
        self.method = method
 
    def __get__(self, obj, T):
        def transaction(*args, **kwargs):
            state = Memento(obj)
            try:
                return self.method(obj, *args, **kwargs)
            except:
                state()
                raise
 
        return transaction
 
 
class NumObj(object):
    def __init__(self, value):
        self.value = value
 
    def __repr__(self):
        return '<%s: %r>' % (self.__class__.__name__, self.value)
 
    def Increment(self):
        self.value += 1
 
    @transactional
    def DoStuff(self):
        self.value = 1111  # <- invalid value
        self.Increment()  # <- will fail and rollback
 
 
if __name__ == '__main__':
    n = NumObj(-1)
    print(n)
    t = Transaction(n)
    try:
        for i in range(3):
            n.Increment()
            print(n)
        t.Commit()
        print('-- commited')
        for i in range(3):
            n.Increment()
            print(n)
        n.value += 'x'  # will fail
        print(n)
    except:
        t.Rollback()
        print('-- rolled back')
    print(n)
    print('-- now doing stuff ...')
    try:
        n.DoStuff()
    except:
        print('-> doing stuff failed!')
        import traceback
 
        traceback.print_exc(0)
        pass
    print(n)

1.3.9 迭代器模式–Iterator

 
'''
Interator
'''
 
 
def count_to(count):
    """Counts by word numbers, up to a maximum of five"""
    numbers = ["one", "two", "three", "four", "five"]
    # enumerate() returns a tuple containing a count (from start which
    # defaults to 0) and the values obtained from iterating over sequence
    for pos, number in zip(range(count), numbers):
        yield number
 
 
# Test the generator
count_to_two = count_to(2)
count_to_five = count_to(5)
 
print('Counting to two...')
for number in count_to_two:
    print(number)
 
print(" ")
 
print('Counting to five...')
for number in count_to_five:
    print(number)
 
print(" ")

1.3.10 解释器模式–Interpreter

 
'''
Interpreter
'''
 
class Context:
    def __init__(self):
        self.input=""
        self.output=""
 
class AbstractExpression:
    def Interpret(self,context):
        pass
 
class Expression(AbstractExpression):
    def Interpret(self,context):
        print("terminal interpret")
 
class NonterminalExpression(AbstractExpression):
    def Interpret(self,context):
        print("Nonterminal interpret")
 
if __name__ == "__main__":
    context= ""
    c = []
    c = c + [Expression()]
    c = c + [NonterminalExpression()]
    c = c + [Expression()]
    c = c + [Expression()]
    for a in c:
        a.Interpret(context)

1.3.11 模版方法–Template Method

 
'''
Template Method
'''
# 模板方法模式概述
#        在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单。在这三个步骤中,点单和买单大同小异,最大的区别在于第二步——吃什么?吃面条和吃满汉全席可大不相同,如图1所示:
#
# 图1 请客吃饭示意图
#         在软件开发中,有时也会遇到类似的情况,某个方法的实现需要多个步骤(类似“请客”),其中有些步骤是固定的(类似“点单”和“买单”),而有些步骤并不固定,存在可变性(类似“吃东西”)。为了提高代码的复用性和系统的灵活性,可以使用一种称之为模板方法模式的设计模式来对这类情况进行设计,在模板方法模式中,将实现功能的每一个步骤所对应的方法称为基本方法(例如“点单”、“吃东西”和“买单”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“请客”)。在模板方法模式中,可以将相同的代码放在父类中,例如将模板方法“请客”以及基本方法“点单”和“买单”的实现放在父类中,而对于基本方法“吃东西”,在父类中只做一个声明,将其具体实现放在不同的子类中,在一个子类中提供“吃面条”的实现,而另一个子类提供“吃满汉全席”的实现。通过使用模板方法模式,一方面提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类,实现完整的“请客”方法,提高系统的灵活性和可扩展性。
#        模板方法模式定义如下:
# 模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
#
# Template Method Pattern:  Define the skeleton of an algorithm in an  operation, deferring some steps to subclasses. Template Method lets  subclasses redefine certain steps of an algorithm without changing the  algorithm's structure.
#        模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式。
#        模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果。模板方法模式提供了一个模板方法来定义算法框架,而某些具体步骤的实现可以在其子类中完成。
#
 
class Register(object):
    '''用户注册接口'''
 
    def register(self):
        pass
    def login(self):
        pass
 
    def auth(self):
        self.register()
        self.login()
 
class RegisterByQQ(Register):
    '''qq注册'''
 
    def register(self):
        print("---用qq注册-----")
 
    def login(self):
        print('----用qq登录-----')
 
 
 
class RegisterByWeiChat(Register):
    '''微信注册'''
 
    def register(self):
        print("---用微信注册-----")
 
    def login(self):
        print('----用微信登录-----')
 
 
if __name__ == "__main__":
 
    register1 = RegisterByQQ()
    register1.login()
 
    register2 = RegisterByWeiChat()
    register2.login()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【设计模式 的相关文章

随机推荐

  • 超分辨率学习记录

    超分辨率学习记录 超分定义 经典模型 前上采样 SRCNN 后上采样 FSRCNN 这篇博客主要内容来自于天池网站的超分辨率理论基础 同时对于其中涉及的学术名词也进行了解释 作为自己学习的记录 注 所有名词右上方带 的下面都有详细解释 博客
  • 最近点对问题

    分而治之 题目来源 Quoit Design Problem Description Have you ever played quoit in a playground Quoit is a game in which flat ring
  • 视频编解码(一):ffmpeg编码H.264帧类型判断

    本文主要讲述ffmpeg编码过程中是如何设置I帧 B帧及P帧的 以及如何通过代码判断帧类型 之前看过很多网上的文章 讲述如何判断I帧 B帧 P帧 然而都是停留在H 264官方文档中的定义 如果不结合ffmpeg 就仿佛纸上谈兵 有点不切实际
  • 人脸识别5.1- insightface人脸检测模型scrfd-训练实战笔记,目标检测的理论理解

    1 insightface detection scrfd模型训练 1 0 数据集 数据集下载说明 https github com deepinsight insightface tree master detection dataset
  • Java面向对象编程

    对于IP地址130 63 160 2 MASK为255 255 255 0 子网号为 A 160 2 B 160 C 63 160 D 130 63 160 答案 B 将网络物理地址转换为IP地址的协议是 A IP B ICMP C ARP
  • uni-app项目中引入uView组件库

    在uni app项目中引入uView组件库 其实uView的官方文档写的很清楚了 但是作为菜鸟踩过坑的我还是记录一下 什么是uView uView是uni app生态专用的UI框架 uni app 是一个使用 Vue js 开发所有前端应用
  • Linux 中的 chmod 命令及示例

    在 Unix 操作系统中 chmod命令用于更改文件的访问模式 该名称是change mode的缩写 其中规定每个文件和目录都有一组权限来控制权限 例如谁可以读取 写入或执行该文件 其中权限分为三类 同时读 写和执行 用 r w 和 x 表
  • Java程序员需看的面试题

    进大厂是大部分程序员的梦想 而进大厂的门槛也是比较高的 所以这里整理了一份阿里 美团 滴滴 头条等大厂面试大全 对于Java后端的朋友来说应该是最全面最完整的面试备战仓库 为了更好地整理每个模块 我也参考了很多网上的优质博文和项目 力求不漏
  • 在父子页面嵌套的结构中,当父页面完成某个操作后给子页面一个回调函数

    企业级系统中有一种常见的页面结构 所有的表单都套在一个父页面里 有业务场景 要求父页面在子页面完成加载后做一些操作 如下 这些代码不是本文的重点内容 不做介绍了 这里的iframe是元素 init my iframe function if
  • 策略模式对象初始化为空解决方案及项目中具体的使用

    使用类 Component public class TaskReceiver Autowired TaskHandlerMapping mapper RabbitHandler RabbitListener queues MqTaskCo
  • 【OPENGLES】opengles-jni实例1

    首先 说明下为什么要用jni实现opengl es 在进行移动端图像算法开发的过程中 需要完成对大量的数据进行处理 opengl是在进行图形渲染或者大批量图像运算处理时有着很大的优势 如果能够在算法库开发中加入opengl 则对于提升算法运
  • dos磁盘管理命令

    dos磁盘管理命令 前言 磁盘管理命令用于日常的磁盘维护 DOS命令行提供了多种文件管理命令用于设置和管理磁盘列表 由于很多磁盘在没有安装图形界面的时候就需要对其进行操作 所以掌握DOS命令行下的磁盘管 理命令对系统管理员是十分必要的 磁盘
  • 区域气象-大气化学在线耦合模式(WRF/Chem)在大气环境领域实践技术应用

    大气污染是工农业生产 生活 交通 城市化等方面人为活动的综合结果 同时气象因素是控制大气污染的关键自然因素 大气污染问题既是局部 当地的 也是区域的 甚至是全球的 本地的污染物排放除了对当地造成严重影响外 同时还会在动力输送作用下 极大地影
  • 【小程序】解析小程序原理

    本文首发自 前端修罗场 一个专注 Web 技术 答疑解惑 面试辅导 职业发展的社区 实际学习过程中 有些同学常常会对小程序和 Web 应用之间的差别产生疑惑 它们之间到底有什么不同 Web 应用不能作为小程序吗 本期文章将会带你比较小程序和
  • JS如何判断是否为null、undefined、NaN

    判断null var exp null if exp typeof exp undefined exp 0 alert is null typeof exp undefined 排除了 undefined exp 0 排除了数字零和 fal
  • 【观影笔记】地平线:大数据时代(BBC)

    地平线 大数据时代 BBC 影片中的实例 大数据分析所需要素 感悟 影片中的实例 洛杉矶 利用预测地震余震发生的模型来预测犯罪 数据挖掘起源 约翰 格兰特Graunt 伦敦黑死病死亡记录 Phil Beales 基因生物学寻找疾病治疗方法
  • PostgreSQL 基本安装总结

    一 Mac 环境下的安装 brew install postgresql 1 1 查看当前环境版本 pg ctl V 1 2 初始化数据库 在开始使用数据库前 需要在磁盘上初始化一个数据库存储区域 通常称之为一个数据库集簇 SQL标准使用的
  • fastjson 问题

    问题 1 fastjson value 为null key 会丢失问题 2 SerializerFeature 配置参数 背景 和第三方系统进行对接 两边商量好了接口定义 有些是非必填项 从数据库查询出来的数据赋值给相应的key 有些Str
  • 会议是浪费工作时间的最佳去处

    本文为翻译初稿 更多精彩内容 敬请关注 高效能程序员的修炼 人民邮电出版社 今天你开了多少个会 这个星期呢 这个月呢 现在你再自问一下 那些会议中有多少是值得参加的 如果把相同的时间用在工作上 你又能完成多少事情 这不禁让人想知道 我们究竟
  • 【设计模式

    every blog every motto You can do more than you think https blog csdn net weixin 39190382 type blog 0 前言 设计模式 上 创建型 设计模式