1.创建型模式

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象

  1. class Singleton(object):
  2. def __init__(self):
  3. pass
  4.  
  5. def __new__(cls, *args, **kwargs):
  6. if not hasattr(Singleton, "_instance"): # 反射
  7. Singleton._instance = object.__new__(cls)
  8. return Singleton._instance
  9.  
  10. obj1 = Singleton()
  11. obj2 = Singleton()
  12. print(obj1, obj2) #<__main__.Singleton object at 0x004415F0> <__main__.Singleton object at 0x004415F0>

单例模式

工厂模式

工厂模式是一个在软件开发中用来创建对象的设计模式。

工厂模式包涵一个超类。这个超类提供一个抽象化的接口来创建一个特定类型的对象,而不是决定哪个对象可以被创建。

为了实现此方法,需要创建一个工厂类创建并返回。

当程序运行输入一个“类型”的时候,需要创建于此相应的对象。这就用到了工厂模式。在如此情形中,实现代码基于工厂模式,可以达到可扩展,可维护的代码。当增加一个新的类型,不在需要修改已存在的类,只增加能够产生新类型的子类。

简短的说,当以下情形可以使用工厂模式:

1.不知道用户想要创建什么样的对象

2.当你想要创建一个可扩展的关联在创建类与支持创建对象的类之间。

一个例子更能很好的理解以上的内容:

  1. 我们有一个基类Person ,包涵获取名字,性别的方法 。有两个子类male 和female,可以打招呼。还有一个工厂类。
  2. 工厂类有一个方法名getPerson有两个输入参数,名字和性别。
  3. 用户使用工厂类,通过调用getPerson方法。

在程序运行期间,用户传递性别给工厂,工厂创建一个与性别有关的对象。因此工厂类在运行期,决定了哪个对象应该被创建

  1. class Person:
  2. def __init__(self):
  3. self.name = None
  4. self.gender = None
  5.  
  6. def getName(self):
  7. return self.name
  8.  
  9. def getGender(self):
  10. return self.gender
  11.  
  12. class Male(Person):
  13. def __init__(self, name):
  14. print "Hello Mr." + name
  15.  
  16. class Female(Person):
  17. def __init__(self, name):
  18. print "Hello Miss." + name
  19.  
  20. class Factory:
  21. def getPerson(self, name, gender):
  22. if gender == M':
  23. return Male(name)
  24. if gender == 'F':
  25. return Female(name)
  26.  
  27. if __name__ == '__main__':
  28. factory = Factory()
  29. person = factory.getPerson("Chetan", "M")

工厂模式

建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

相关模式:思路和模板方法模式很像,模板方法是封装算法流程,对某些细节,提供接口由子类修改,建造者模式更为高层一点,将所有细节都交由子类实现

一个例子更能很好的理解以上的内容:

1. 有一个接口类,定义创建对象的方法。一个指挥员类,接受创造者对象为参数。两个创造者类,创建对象方法相同,内部创建可自定义

2.一个指挥员,两个创造者(瘦子 胖子),指挥员可以指定由哪个创造者来创造

  1. from abc import ABCMeta, abstractmethod
  2.  
  3. class Builder():
  4. __metaclass__ = ABCMeta
  5.  
  6. @abstractmethod
  7. def draw_left_arm(self):
  8. pass
  9.  
  10. @abstractmethod
  11. def draw_right_arm(self):
  12. pass
  13.  
  14. @abstractmethod
  15. def draw_left_foot(self):
  16. pass
  17.  
  18. @abstractmethod
  19. def draw_right_foot(self):
  20. pass
  21.  
  22. @abstractmethod
  23. def draw_head(self):
  24. pass
  25.  
  26. @abstractmethod
  27. def draw_body(self):
  28. pass
  29.  
  30. class Thin(Builder):
  31. def draw_left_arm(self):
  32. print '画左手'
  33.  
  34. def draw_right_arm(self):
  35. print '画右手'
  36.  
  37. def draw_left_foot(self):
  38. print '画左脚'
  39.  
  40. def draw_right_foot(self):
  41. print '画右脚'
  42.  
  43. def draw_head(self):
  44. print '画头'
  45.  
  46. def draw_body(self):
  47. print '画瘦身体'
  48.  
  49. class Fat(Builder):
  50. def draw_left_arm(self):
  51. print '画左手'
  52.  
  53. def draw_right_arm(self):
  54. print '画右手'
  55.  
  56. def draw_left_foot(self):
  57. print '画左脚'
  58.  
  59. def draw_right_foot(self):
  60. print '画右脚'
  61.  
  62. def draw_head(self):
  63. print '画头'
  64.  
  65. def draw_body(self):
  66. print '画胖身体'
  67.  
  68. class Director():
  69. def __init__(self, person):
  70. self.person=person
  71.  
  72. def draw(self):
  73. self.person.draw_left_arm()
  74. self.person.draw_right_arm()
  75. self.person.draw_left_foot()
  76. self.person.draw_right_foot()
  77. self.person.draw_head()
  78. self.person.draw_body()
  79.  
  80. if __name__=='__main__':
  81. thin=Thin()
  82. fat=Fat()
  83. director_thin=Director(thin)
  84. director_thin.draw()
  85. director_fat=Director(fat)
  86. director_fat.draw()

建造者模式

原型模式

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式本质就是克隆对象,所以在对象初始化操作比较复杂的情况下,很实用,能大大降低耗时,提高性能,因为“不用重新初始化对象,而是动态地获得对象运行时的状态”。

浅拷贝(Shallow Copy):指对象的字段被拷贝,而字段引用的对象不会被拷贝,拷贝的对象和源对象只是名称相同,但是他们共用一个实体。
深拷贝(deep copy):对对象实例中字段引用的对象也进行拷贝。

  1. import copy
  2. from collections import OrderedDict
  3.  
  4. class Book:
  5. def __init__(self, name, authors, price, **rest):
  6. '''rest的例子有:出版商、长度、标签、出版日期'''
  7. self.name = name
  8. self.authors = authors
  9. self.price = price # 单位为美元
  10. self.__dict__.update(rest)
  11.  
  12. def __str__(self):
  13. mylist = []
  14. ordered = OrderedDict(sorted(self.__dict__.items()))
  15. for i in ordered.keys():
  16. mylist.append('{}: {}'.format(i, ordered[i]))
  17. if i == 'price':
  18. mylist.append('$')
  19. mylist.append('\n')
  20. return ''.join(mylist)
  21.  
  22. class Prototype:
  23. def __init__(self):
  24. self.objects = dict()
  25.  
  26. def register(self, identifier, obj):
  27. self.objects[identifier] = obj
  28.  
  29. def unregister(self, identifier):
  30. del self.objects[identifier]
  31.  
  32. def clone(self, identifier, **attr):
  33. found = self.objects.get(identifier)
  34. if not found:
  35. raise ValueError('Incorrect object identifier: {}'.format(identifier))
  36. obj = copy.deepcopy(found)
  37. obj.__dict__.update(attr)
  38. return obj
  39.  
  40. def main():
  41. b1 = Book('The C Programming Language', ('Brian W. Kernighan', 'Dennis M.Ritchie'),
  42. price=118, publisher='Prentice Hall', length=228, publication_date='1978-02-22',
  43. tags=('C', 'programming', 'algorithms', 'data structures'))
  44. prototype = Prototype()
  45. cid = 'k&r-first'
  46. prototype.register(cid, b1)
  47. b2 = prototype.clone(cid, name='The C Programming Language(ANSI)', price=48.99,
  48. length=274, publication_date='1988-04-01', edition=2)
  49. for i in (b1, b2):
  50. print(i)
  51. print("ID b1 : {} != ID b2 : {}".format(id(b1), id(b2)))
  52.  
  53. if __name__ == '__main__':
  54. main()
  55.  
  56. """
  57. >>> python3 prototype.py
  58. authors: ('Brian W. Kernighan', 'Dennis M. Ritchie')
  59. length: 228
  60. name: The C Programming Language
  61. price: 118$
  62. publication_date: 1978-02-22
  63. publisher: Prentice Hall
  64. tags: ('C', 'programming', 'algorithms', 'data structures')
  65.  
  66. authors: ('Brian W. Kernighan', 'Dennis M. Ritchie')
  67. edition: 2
  68. length: 274
  69. name: The C Programming Language (ANSI)
  70. price: 48.99$
  71. publication_date: 1988-04-01
  72. publisher: Prentice Hall
  73. tags: ('C', 'programming', 'algorithms', 'data structures')
  74.  
  75. ID b1 : 140004970829304 != ID b2 : 140004970829472
  76. """

原型模式

2.结构型模式

适配器模式

所谓适配器模式是指是一种接口适配技术,它可通过某个类来使用另一个接口与之不兼容的类,运用此模式,两个类的接口都无需改动。

适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况,比如在需要对早期代码复用一些功能等应用上很有实际价值。

解释二:

适配器模式(Adapter Pattern):将一个类的接口转换成为客户希望的另外一个接口.Adapter Pattern使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.
应用场景:系统数据和行为都正确,但接口不符合时,目的是使控制范围之外的一个原有对象与某个接口匹配,适配器模式主要应用于希望复用一些现存的类,但接口又与复用环境不一致的情况

  1. class Target(object):
  2. def request(self):
  3. print "普通请求"
  4.  
  5. class Adaptee(object):
  6.  
  7. def specific_request(self):
  8. print "特殊请求"
  9.  
  10. class Adapter(Target):
  11.  
  12. def __init__(self):
  13. self.adaptee = Adaptee()
  14.  
  15. def request(self):
  16. self.adaptee.specific_request()
  17.  
  18. if __name__ == "__main__":
  19. target = Adapter()
  20. target.request()

适配器模式

修饰器模式

该模式虽名为修饰器,但这并不意味着它应该只用于让产品看起来更漂亮。修饰器模式通常用于扩展一个对象的功能。这类扩展的实际例子有,给枪加一个消音器、使用不同的照相机镜头

  1. import functools
  2. def memoize(fn):
  3. known = dict()
  4. @functools.wraps(fn)
  5. def memoizer(*args):
  6. if args not in known:
  7. known[args] = fn(*args)
  8. return known[args]
  9. return memoizer
  10. @memoize
  11. def nsum(n):
  12. '''返回前n个数字的和'''
  13. assert(n >= 0), 'n must be >= 0'
  14. return 0 if n == 0 else n + nsum(n-1)
  15. @memoize
  16. def fibonacci(n):
  17. '''返回斐波那契数列的第n个数'''
  18. assert(n >= 0), 'n must be >= 0'
  19. return n if n in (0, 1) else fibonacci(n-1) + fibonacci(n-2)
  20. if __name__ == '__main__':
  21. from timeit import Timer
  22. measure = [ {'exec':'fibonacci(100)', 'import':'fibonacci',
  23. 'func':fibonacci},{'exec':'nsum(200)', 'import':'nsum',
  24. 'func':nsum} ]
  25. for m in measure:
  26. t = Timer('{}'.format(m['exec']), 'from __main__ import{}'.format(m['import']))
  27. print('name: {}, doc: {}, executing: {}, time:{}'.format(m['func'].__name__, m['func'].__doc__,m['exec'], t.timeit()))
  28.  
  29. """
  30. >>> python3 mymath.py
  31. name: fibonacci, doc: Returns the nth number of the Fibonacci
  32. sequence, executing: fibonacci(100), time: 0.4169441329995607
  33. name: nsum, doc: Returns the sum of the first n numbers,
  34. executing: nsum(200), time: 0.4160157349997462
  35. """

修饰器模式

外观模式

外观模式又叫做门面模式。在面向对象程序设计中,解耦是一种推崇的理念。但事实上由于某些系统中过于复杂,从而增加了客户端与子系统之间的耦合度。例如:在家观看多媒体影院时,更希望按下一个按钮就能实现影碟机,电视,音响的协同工作,而不是说每个机器都要操作一遍。这种情况下可以采用外观模式,即引入一个类对子系统进行包装,让客户端与其进行交互。

外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。

  1. from enum import Enum
  2. from abc import ABCMeta, abstractmethod
  3.  
  4. State = Enum('State', 'new running sleeping restart zombie')
  5.  
  6. class User:
  7. pass
  8.  
  9. class Process:
  10. pass
  11.  
  12. class File:
  13. pass
  14.  
  15. class Server(metaclass=ABCMeta):
  16. @abstractmethod
  17. def __init__(self):
  18. pass
  19.  
  20. def __str__(self):
  21. return self.name
  22.  
  23. @abstractmethod
  24. def boot(self):
  25. pass
  26.  
  27. @abstractmethod
  28. def kill(self, restart=True):
  29. pass
  30.  
  31. class FileServer(Server):
  32. def __init__(self):
  33. '''初始化文件服务进程要求的操作'''
  34. self.name = 'FileServer'
  35. self.state = State.new
  36.  
  37. def boot(self):
  38. print('booting the {}'.format(self))
  39. '''启动文件服务进程要求的操作'''
  40. self.state = State.running
  41.  
  42. def kill(self, restart=True):
  43. print('Killing {}'.format(self))
  44. '''终止文件服务进程要求的操作'''
  45. self.state = State.restart if restart else State.zombie
  46.  
  47. def create_file(self, user, name, permissions):
  48. '''检查访问权限的有效性、用户权限等'''
  49. print("trying to create the file '{}' for user '{}' with permissions{}".format(name, user, permissions))
  50.  
  51. class ProcessServer(Server):
  52. def __init__(self):
  53. '''初始化进程服务进程要求的操作'''
  54. self.name = 'ProcessServer'
  55. self.state = State.new
  56.  
  57. def boot(self):
  58. print('booting the {}'.format(self))
  59. '''启动进程服务进程要求的操作'''
  60. self.state = State.running
  61.  
  62. def kill(self, restart=True):
  63. print('Killing {}'.format(self))
  64. '''终止进程服务进程要求的操作'''
  65. self.state = State.restart if restart else State.zombie
  66.  
  67. def create_process(self, user, name):
  68. '''检查用户权限和生成PID等'''
  69. print("trying to create the process '{}' for user '{}'".format(name, user))
  70.  
  71. class WindowServer:
  72. pass
  73.  
  74. class NetworkServer:
  75. pass
  76.  
  77. class OperatingSystem:
  78. '''外观'''
  79.  
  80. def __init__(self):
  81. self.fs = FileServer()
  82. self.ps = ProcessServer()
  83.  
  84. def start(self):
  85. [i.boot() for i in (self.fs, self.ps)]
  86.  
  87. def create_file(self, user, name, permissions):
  88. return self.fs.create_file(user, name, permissions)
  89.  
  90. def create_process(self, user, name):
  91. return self.ps.create_process(user, name)
  92.  
  93. def main():
  94. os = OperatingSystem()
  95. os.start()
  96. os.create_file('foo', 'hello', '-rw-r-r')
  97. os.create_process('bar', 'ls /tmp')
  98.  
  99. if __name__ == '__main__':
  100. main()
  101.  
  102. """
  103. booting the FileServer
  104. booting the ProcessServer
  105. trying to create the file 'hello' for user 'foo' with permissions-rw-r-r
  106. trying to create the process 'ls /tmp' for user 'bar'
  107. """

外观模式

享元模式

运用共享技术有效地支持大量细粒度的对象。
内部状态:享元对象中不会随环境改变而改变的共享部分。比如围棋棋子的颜色。
外部状态:随环境改变而改变、不可以共享的状态就是外部状态。比如围棋棋子的位置。

应用场景:程序中使用了大量的对象,如果删除对象的外部状态,可以用相对较少的共享对象取代很多组对象,就可以考虑使用享元模式。

  1. import random
  2. from enum import Enum
  3. TreeType = Enum('TreeType', 'apple_tree cherry_tree peach_tree')
  4.  
  5. class Tree:
  6. pool = dict()
  7. def __new__(cls, tree_type):
  8. obj = cls.pool.get(tree_type, None)
  9. if not obj:
  10. obj = object.__new__(cls)
  11. cls.pool[tree_type] = obj
  12. obj.tree_type = tree_type
  13. return obj
  14.  
  15. def render(self, age, x, y):
  16. print('render a tree of type {} and age {} at ({}, {})'.format(self.tree_type, age, x, y))
  17.  
  18. def main():
  19. rnd = random.Random()
  20. age_min, age_max = 1, 30 # 单位为年
  21. min_point, max_point = 0, 100
  22. tree_counter = 0
  23. for _ in range(10):
  24. t1 = Tree(TreeType.apple_tree)
  25. t1.render(rnd.randint(age_min, age_max),
  26. rnd.randint(min_point, max_point),
  27. rnd.randint(min_point, max_point))
  28. tree_counter += 1
  29. for _ in range(3):
  30. t2 = Tree(TreeType.cherry_tree)
  31. t2.render(rnd.randint(age_min, age_max),
  32. rnd.randint(min_point, max_point),
  33. rnd.randint(min_point, max_point))
  34. tree_counter += 1
  35. for _ in range(5):
  36. t3 = Tree(TreeType.peach_tree)
  37. t3.render(rnd.randint(age_min, age_max),
  38. rnd.randint(min_point, max_point),
  39. rnd.randint(min_point, max_point))
  40. tree_counter += 1
  41.  
  42. print('trees rendered: {}'.format(tree_counter))
  43. print('trees actually created: {}'.format(len(Tree.pool)))
  44. t4 = Tree(TreeType.cherry_tree)
  45. t5 = Tree(TreeType.cherry_tree)
  46. t6 = Tree(TreeType.apple_tree)
  47. print('{} == {}? {}'.format(id(t4), id(t5), id(t4) == id(t5)))
  48. print('{} == {}? {}'.format(id(t5), id(t6), id(t5) == id(t6)))
  49.  
  50. main()
  51.  
  52. """
  53. render a tree of type TreeType.apple_tree and age 28 at (29, 80)
  54. render a tree of type TreeType.apple_tree and age 28 at (38, 94)
  55. render a tree of type TreeType.apple_tree and age 16 at (82, 84)
  56. render a tree of type TreeType.apple_tree and age 18 at (43, 98)
  57. render a tree of type TreeType.apple_tree and age 2 at (84, 72)
  58. render a tree of type TreeType.apple_tree and age 16 at (89, 29)
  59. render a tree of type TreeType.apple_tree and age 30 at (91, 53)
  60. render a tree of type TreeType.apple_tree and age 12 at (92, 73)
  61. render a tree of type TreeType.apple_tree and age 3 at (11, 54)
  62. render a tree of type TreeType.apple_tree and age 1 at (34, 59)
  63. render a tree of type TreeType.cherry_tree and age 11 at (67, 72)
  64. render a tree of type TreeType.cherry_tree and age 27 at (65, 81)
  65. render a tree of type TreeType.cherry_tree and age 27 at (10, 48)
  66. render a tree of type TreeType.peach_tree and age 11 at (35, 38)
  67. render a tree of type TreeType.peach_tree and age 3 at (58, 83)
  68. render a tree of type TreeType.peach_tree and age 18 at (73, 50)
  69. render a tree of type TreeType.peach_tree and age 24 at (94, 3)
  70. render a tree of type TreeType.peach_tree and age 4 at (2, 9)
  71. trees rendered: 18
  72. trees actually created: 3
  73. 4866032 == 4866032? True
  74. 4866032 == 4742704? False
  75.  
  76. """

享元模式

模型-视图-控制器模式

代理模式

3.行为型模式

责任链模式

命令模式

解释器模式

观察者模式

状态模式

策略模式

模板模式

常见设计模式 (python代码实现)的更多相关文章

  1. 研磨设计模式解析及python代码实现——(二)外观模式(Facade)

    一.外观模式定义 为子系统中的一组接口提供一个一致的界面,使得此子系统更加容易使用. 二.书中python代码实现 class AModuleApi: def testA(self): pass cl ...

  2. Python代码样例列表

    扫描左上角二维码,关注公众账号 数字货币量化投资,回复“1279”,获取以下600个Python经典例子源码 ├─algorithm│       Python用户推荐系统曼哈顿算法实现.py│    ...

  3. 学习 27 门编程语言的长处,提升你的 Python 代码水平

    Python猫注:Python 语言诞生 30 年了,如今的发展势头可谓如火如荼,这很大程度上得益于其易学易用的优秀设计,而不可否认的是,Python 从其它语言中偷师了不少.本文作者是一名资深的核心 ...

  4. [转] Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  5. Python代码性能优化技巧

    摘要:代码优化能够让程序运行更快,可以提高程序的执行效率等,对于一名软件开发人员来说,如何优化代码,从哪里入手进行优化?这些都是他们十分关心的问题.本文着重讲了如何优化Python代码,看完一定会让你 ...

  6. Python 代码性能优化技巧(转)

    原文:Python 代码性能优化技巧 Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化. ...

  7. Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  8. 六行python代码的爱心曲线

    前些日子在做绩效体系的时候,遇到了一件囧事,居然忘记怎样在Excel上拟合正态分布了,尽管在第二天重新拾起了Excel中那几个常见的函数和图像的做法,还是十分的惭愧.实际上,当时有效偏颇了,忽略了问题 ...

  9. 200行Python代码实现2048

    200行Python代码实现2048 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面 ...

随机推荐

  1. python入门学习记录(win7+python3.6)

    1. pip freeze 可以查看安装的模块信息 2. 查看某个模块是否已经安装了 conda(pip) search <moduleName>.图一显示为未安装,图二显示为已经安装

  2. Kestrel.Transport.Sockets分析与使用

    相信大家都清楚asp core有着非常出色的性能,它出色的性能也源于网络服务模块Kestrel:在techempower测试中Kestrel基础核心达到了700万级别的RPS吞吐能力,具备这样的能力那 ...

  3. C#2.0 委托

    委托 委托是一个非常不错的设计,允许我们把方法做为参数传递,实现了开放閉放原则.在方法中我们只要有一个委托占位,调用者就可以传入符合签名的方法来做不同的操作,这也面向对象开发中多态的魅力. 但是在C# ...

  4. ansible学习系列1-ansible简介

    1.ansible简介 官方说明:Ansible is an IT automation tool. It can configure systems, deploy software, and or ...

  5. 附实例!图解React的生命周期及执行顺序

    本文由云+社区发表 作者:前端林子 1.七个可选的生命周期 可以结合下图来看: (1) componentWillMount() 仅在render()方法前被调用一次,如果在该方法中调用了setSta ...

  6. [二十一]JavaIO之BufferedReader 与 BufferedWriter

    功能简介 BufferedReader  从字符输入流中读取文本,内部缓冲各个字符,从而实现字符.数组和行的高效读取 BufferedWriter 将文本写入字符输出流,内部缓冲各个字符,从而提供单个 ...

  7. [四] java8 函数式编程 收集器浅析 收集器Collector常用方法 运行原理 内部实现

    Collector常见用法     常用形式为:   .collect(Collectors.toList()) collect()是Stream的方法 Collectors  是收集器Collect ...

  8. OO第一单元作业总结

    oo第一单元的作业是对多项式的求导.下面就是对三次作业分别进行分析. 第一次作业 分析 第一次作业相对来讲比较简单,甚至不用面向对象的思想都能十分轻松的完成(实际上自己就没有使用),包含的内容只有常数 ...

  9. MySQL主从复制配置指导及PHP读写分离源码分析

    开发环境 master环境:ubuntu16.04.5LTS/i5/8G/500G/64位/mysql5.7.23/php7/apache2 slave环境:kvm虚拟机/ubuntu14.04.01 ...

  10. MySQL外键设置中的的 Cascade、NO ACTION、Restrict、SET NULL

    例如: ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo FOREIGN KEY(gradeid) REFERENCES grade(id) ON DELET ...