写点什么

架构师训练营第三周作业和小记

用户头像
tuuezzy
关注
发布于: 2020 年 06 月 25 日

以下是架构师训练营第三周作业


1、手写单例模式代码。


----------------------------------------------------------------------------

2、用组合设计模式编写程序,打印输出图 1 的窗口,窗口组件的树结构如图 2 所示,打印输出示例参考图 3。


类图


Component 实现 Printable 接口,Container 继承 Component 类,添加 addChild 等函数用于向 childList 加入 Component 组件对象。


Python 语言代码(Component 处回车显示格式和输入时不同)

class Printable:    def print(self):        pass
class Component(Printable): def __init__(self, type, name): self.type = type self.name = name def print(self): print("print %s(%s)"% (self.type, self.name)) def __str__(self): return self.name def addChild(self,child): pass
class Container(Component): #childList = [] #如果定义了数组,会所有的实例都用这个数组 def __init__(self, type, name): super(Container, self).__init__(type, name) self.childList = [] def addChild(self,child): self.childList.append(child) def removeChild(self, child): #check and remove a child if isinstance(child, Component): for i in self.childList: if i.type == child.type and i.name == child.name: self.childList.remove(i) return True return False def checkChild(self, child): #check a child if isinstance(child, Component): for i in self.childList: if i.type == child.type and i.name == child.name: return True return False def addChildren(self, children): if children.__iter__(): self.childList += children def toStr(self): if self.childList is not None: print("List:") print(self.childList) else: print("List is empty.") def print(self): #overwrite the print function for Container super(Container, self).print() for i in self.childList: i.print()class Frame(Container): def __init__(self, name): super(Frame, self).__init__("Frame", name) #self.type = "Frame" self.name = nameclass Winform(Container): def __init__(self, name): super(Winform, self).__init__("Winform", name) self.type = "Winform" self.name = nameclass Button(Component): def __init__(self, name): self.type = "Button" self.name = nameclass Label(Component): def __init__(self, name): self.type = "Label" self.name = name def setLabel(self, labelText): passclass TextBox(Component): def __init__(self, name): self.type = "TextBox" self.name = name def setText(self, text): passclass PasswordBox(TextBox): def __init__(self, name): self.type = "PasswordBox" self.name = name def checkPassword(self): passclass CheckBox(Component): def __init__(self, name): self.type = "CheckBox" self.name = nameclass LinkLabel(Label): def __init__(self, name): self.type = "LinkLabel" self.name = name def link(self, Address): pass
class Client: def run(self): winForm = Winform( "Windows窗口") Pictrue = Component("Pictrue", "LOGO图片") winForm.addChild(Pictrue) button1 = Button("登录") button2 = Button("注册") winForm.addChild(button1) winForm.addChild(button2)
frame = Frame("FRAME1") ComponentList = [ Label("用户名"), TextBox("文本框"), Label("密码"), PasswordBox("密码框"), CheckBox("复选框"), TextBox("记住用户名"), LinkLabel("忘记密码"), ] frame.addChildren(ComponentList) winForm.addChild(frame) winForm.print() if __name__ == "__main__": client = Client() client.run()
复制代码


输出


----------------------------------------------------------------------------

3、总结:

本周使用几个实例来讲解了多个设计模式的应用。(第三周讲课内容有第二周课件后 1/3 部分)

一、响应式服务编程以及 Flower 框架

响应式服务编程有以下几个特点:

  • 即时响应,应用的调用者可以即时得到响应,无需等到整个应用程序执行完毕,也就是说应用调用是非阻塞的。

  • 回弹性,当应用程序部分功能失效的时候,应用系统本身能够进行自我修复,保证正常运行,保证响应,不会出现系统崩溃和宕机。

  • 弹性,能够对应用负载压力做出响应,能够自动伸缩以适应应用负载压力,根据压力自动调整自身的处理能力,或者根据自身的处理能力,调整进入系统中的访问请求数量。

  • 消息驱动,功能模块之间、服务之间,通过消息进行驱动,完成服务的流程。


Flower 如何解决这个问题的?


对 Flower 而言,只需要有限的几个线程,就可以完成全部的用户请求操作。当并发用户到达应用服务器的时候,Flower 只需要极少的容器线程就可以处理所有的并发用户请求。这个线程并不会执行真正的业务操作,它只是将用户的请求变为请求对象以后,将请求对象异步交给 Flower 的 Service 去处理,自身立刻就返回。因为容器线程不做太多的工作,所以极少的线程就可以满足高并发的用户的请求,用户的请求不会被阻塞,不会因为线程不够而无法处理。

用户请求交给 Flower 的 Service 对象以后,Service 之间依然是使用异步的消息通讯的方式进行调用,Service 之间也不会直接进行阻塞式的调用。一个 Service 完成业务逻辑处理计算以后,会返回一个处理结果,这个结果以消息的方式异步发送给它的下一个 Service,Service 之间使用了 AKKA Actor 进行消息通信,也是只需要有限的几个线程就可以完成大量的 Service 处理和消息传输。

上面提到 Web 应用主要的线程阻塞,是因为数据库的访问导致的线程阻塞。Flower 支持异步数据库驱动,用户请求数据库的时候,将请求提交给异步数据库驱动,立刻就返回,不会阻塞当前线程,异步数据库访问连接远程的数据库,进行真正的数据库操作,得到结果以后,将结果以异步回调的方式发送给 Flower 的 Service 进行进一步的处理,这个时候依然不会有线程被阻塞。也就是说使用 Flower 开发的系统,在一个典型的 Web 应用中,几乎没有任何地方会被阻塞,所有的线程都可以被不断复用,有限的线程就可以完成大量的并发用户请求,从而极大地提高了系统的吞吐能力,也极大地提高了系统的响应时间。

主要应用了 AKKA 的 Actor 进行通信。那么 AKKA Actor 又是如何实现异步消息通信的呢?下面是 AKKA Actor 架构图。

注意:架构中使用 message 仍然不可避免的对 Message Queue 等软件所在的硬件配置和处理速度有要求,从这一点上来说,软件工程仍然不存在银弹。

二、讲解了面向对象的设计模式

定义:

每一种模式都描述了一种问题的通用解决方案。这种问题在我们的环境中,不停地出现。

设计模式是一种可重复使用的解决方案。

一个设计模式的四个部分:

模式的名称 - 由少量的字组成的名称,有助于我们表达我们的设计。

待解问题 - 描述了何时需要运用这种模式,以及运用模式的环境(上下文)。

解决方案 - 描述了组成设计的元素(类和对象)、它们的关系、职责以及合作。但这种解决方案是抽象的,它不代表具体的实现。

结论 - 运用这种方案所带来的利和弊。主要是指它对系统的弹性、扩展性和可移植性的影响。

设计模式的分类

从功能分

创建模式(Creational Patterns)

☞ 对类的实例化过程的抽象。

结构模式(Structural Patterns)

☞ 将类或对象结合在一起形成更大的结构。

行为模式(Behavioral Patterns)

☞ 对在不同的对象之间划分责任和算法的抽象化。

从方式分:类模式和对象模式

下面分别讲述了一些设计模式。有大量的参考资料,不再赘述。

以 JUnit 为例,讲述了工厂模式。以 Spring 为例讲述了工厂模式和单例模式。重点是 Spring 的 DI 和 IoC 的实现。

作为前端框架,Spring 也不可避免的使用了 MVC 模式。


三、Panthera 代码解析

Panthera 是一种大数据仓库引擎,分析了这个引擎中的组合模式和装饰器模式。回顾了抽象语法树 AST。

四、软件设计的原则

软件设计需要遵循如下原则:

  1. 单一职责原则 SRP

  2. 开放封闭原则 OCP

  3. 里氏替换原则 LSP

  4. 依赖倒置原则 DIP

  5. 接口隔离原则 ISP

还有 Law of Demeter:迪米特法则

把这六个原则的首字母合起来(两个 L 算做一个)就是 SOLID (稳定的),其代表的含义就是这六个原则结合使用的好处:建立稳定、灵活、健壮的设计。


发布于: 2020 年 06 月 25 日阅读数: 81
用户头像

tuuezzy

关注

还未添加个人签名 2017.10.17 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第三周作业和小记