写点什么

架构设计篇之面向对象设计

发布于: 2020 年 07 月 07 日

前言

无论是一款产品 APP 或者是汽车都有着自己的演进过程,而编程的思想也是一直在演进,如果说我们现在有多么的科技发达,实际上都是站在了巨人的肩膀上,感谢前辈们的付出,下面是简单描绘的演进图。


一、OOP

面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙一个事物在整个解决问题的步骤中的行为。面向对象程序设计中的概念主要包括:对象、类、数据抽象、继承、动态绑定、数据封装、多态性、消息传递。通过这些概念面向对象的思想得到了具体的体现。


二、核心概念

2.1、类

类是面向对象领域的最基础的一个概念,也是面向对象分析和设计的基石。

我们看一段代码

public class FlyBird{    //眼睛   private String eye;  //嘴   private String mouth;  //腿   private String leg;  //飞   public void fly(){   }}
复制代码


那么人以类聚,物以群分。你会发现我们可以抽象出一个个的类,实际上是有着共同的特性的抽象的说明。比如鸟类一部分会飞我们可以抽象出上面的类 FlyBird.如果不会飞的鸟比如鸵鸟我们又可以定义一种不会飞的鸟。

public class NotFlyBird{    //眼睛   private String eye;  //嘴   private String mouth;  //腿   private String leg;  //不会飞   public void Notfly(){   }}
复制代码

那么如何定义一个类呢?面向对象程序设计主要的思想就是扩展性,复用性,那么类其实就是复用的聚合并提供了抽象的实现。

2.2、对象

对象,我们对于自己的媳妇、妻子会说对象。

那么软件中的对象和现实的对象分别指代的是什么呢?

现实的对象


软件的对象

FlyBird 对象 = new FlyBird();
复制代码



你是不是有很多黑人问号?软件的对象是个啥?其实软件对象的实体代表的是软件里面会飞的鸟,如果来表达现实中的意义的话就是如下图了。

对象是软件中对于抽象类的一种具体指代,如果你指的类是鸟类,那么对象就会成为具体是鹦鹉还是老鹰还是小麻雀。

2.3、接口

接口我们现在通常认为的就是 USB 接口或者插排接口,那么实际上软件中的接口与其相似。

比如你是顾客,我是商家,你告诉我说想买瓶饮料,我需要给你一个窗口提供给你,然后其他顾客想要更多的其他商品,eg 如下图:

那么现在如果顾客越来越多,是不是我们可以定义个对接的方式,你输入一个东西,我这边给你映射的一个东西。比如你要饮料(冰红茶,3 元一瓶,3 元钱),那么我直接给你🥤饮料。比如你要方便面(康师傅,1 桶面,5 元钱),那么我直接你个方便面。我只需你给我确定的输入,我给你确定的输出就可以了。如果我这里没有对应你的输入,那么直接告诉你没有。


在我们刚才的现实中,上面描述的就是对应软件的接口的一种抽象表达。

2.4、抽象

上面说了很多抽象,比如画家分为抽象主义,现实主义。那么我们这里的抽象实际上就是刚才上面说的一种共性的提炼和表达形式。

2.5、继承

子承父业,这里说的承就是继承父亲的留下的基业。这里的继承是相同的,软件中也会有子类,父类,子类继承父类,就叫做继承。那么父亲可以有多个儿子,但是儿子必须只有一个亲生父亲。所以软件领域中就会有着相同的定义,继承只能单继承。

2.6、封装

在我们提到的接口中,顾客的角色并不知道商家店铺的规模,如何加工,是外采还是自己制作。而这里的话就是封装,对于顾客不需要关心的内容,全部封装不可见。只让你关注你可见的内容。

2.7、多态

与继承相似,刚才我们提到过儿子只有一个亲生父亲,但是父亲可以有多个儿子,那么在我们这里要说明的就是与现实相通,一个父亲可以有大儿子,二儿子,三儿子,四闺女。那么这些孩子你会有生活经验,他们的性格,长相,受教育的程度都会有变化,而这些其实就是我们说的多态。

三、面向对象的程序设计的生命周期

面向对象的程序设计的生命周期:

从上图中我们可以看到一个需求到新的需求产生闭环。什么时候会停止呢?

比如腾讯的赛马机制或者滴滴和美团相同的业务冲突,阿里淘宝和京东商城,苏宁和国美等等。只要是有市场用户需求,就会有竞品和竞争对手。一旦发生了大众点评和美团合并了,新美大,或者公司倒闭了,破产了,用户需求未挖到根本痛点,则这个时候需要被合并的应用需求就可以停止了。

那么我们概括下作为程序设计者的角度来看:

  • 需求分析阶段:与领域专家或者调研用户等,通过沟通或者采集得到需求进行分析,进行需求建模。多次沟通达到明确需求,明确用户痛点。

  • 原型设计阶段:关于需求明确,根据需求模型,画出原型图,提炼出领域相关的知识

  • 设计开发阶段:根据原型,对象抽象设计,数据结构设计,架构设计,接口设计,资源评估,技术实施。

  • 测试保障阶段:根据开发的产物,进行黑盒测试,白盒测试,冒烟测试,灰度测试,AB 测试等等手段来保障产物可以达到可交付状态。

  • 运维售后阶段:如果是甲乙双方公司,则可能需要签署售后服务,如果是本属同一个公司,则需要 SRE 运维团队和研发开发团队来保证产物的质量平稳提供服务。


四、架构设计

在我们面向程序设计的过程中,根据前面的巨人大师总结了如下设计原则

4.1、设计原则


4.1.1、开闭原则(Open-Closed Principle, OCP)

开闭原则是设计模式的第一大原则,它的潜台词是:控制需求变动风险,缩小维护成本。也就是说我们在编写代码的时候要有良好的扩展性,要求很高的抽象和复用性。这样在每次需求变动的时候你不会推翻原来的设计方案。

4.1.2、单一职责原则(Single Responsibility Principle, SRP)


单一职责的潜台词是:拆分到最小单位,解决复用和组合问题。如上文所说,类本身就是对于共性事物的抽象,一个类只负责一个功能领域的相应职责,职责分工明确放佛和团队中工作一样,你只负责测试,他只负责开发,另外同事是前端和产品。这样你们的复用和组合就会产生更多的可能性。切忌一个类做了很多不相关的事情糅合到一起,比如曾见过 4、5 千行代码在一个接口里面,各种判断路径。后期维护增加很大的成本。

4.1.3、里氏代换原则(Liskov Substitution Principle, LSP)

此原则的含义是子类可以在任何地方替换它的父类。解释一下,这是多态的前提,里氏替换原则的潜台词是:尽量使用精准的抽象类或者接口。我们利用该特性可以实现反射或者代理实现。具体的执行操作由子类执行,而代表类则是父类。

4.1.4、依赖倒转原则(Dependence Inversion Principle, DIP)

依赖倒置原则就是要求调用者和被调用者都依赖抽象,依赖倒置的潜台词是:面向抽象编程,解耦调用和被调用者。这样也是为了应付后期的扩展性,如果一方有变化可以尽量缩小变化的范围。

4.1.5、接口隔离原则(Interface Segregation Principle, ISP)

接口隔离实际上和单一职能原则类似,一个接口可有多个接口。在我们上面描述的过程中,接口是约定双方的一种协议。所以如果现在依然顾客和商家举例,接口需要支持美国友人的购买(需要懂英文),接口需要支持全世界的友人的购买(需要懂各种语言)。这里你就明白了,一个接口也可以完成,但是扩展的后期就会违背了单一职责原则,糅合的太多,代码越来越复杂。所以最好的方式就是入口杜绝,接口隔离。

4.1.6、合成复用原则(Composite Reuse Principle, CRP)

如果只是达到代码复用的目的,尽量使用组合与聚合,而不是继承。因为继承只能无限扩展你的父类后期维护艰难,而抽出复用的代码逻辑,达到复用,后期移除或者变更需求都影响面只有改动局部位置。

4.1.7、迪米特法则(Law of Demeter, LoD)


迪米特原则要求尽量的封装,尽量的独立,尽量的使用低级别的访问修饰符,其实是封装特性的体现。你不应该知道的信息,我尽量不让你知道。


4.2、设计模型

4.2.1、单体架构设计

4.2.1.1、J2EE 架构


J2EE 平台由一整套服务(services)、应用程序接口(APIs)和协议构成,它对开发基于 Web 的多层应用提供了功能支持。早期很多系统没有框架没有高并发的用户场景都是基于单体应用开发的。

4.2.1.2、SSH 架构


集成 SSH 框架的系统从职责上分为四层:表示层、业务逻辑层、数据持久层和域模块层,以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的 Web 应用程序。其中使用 Struts 作为系统的整体基础架构,负责 MVC 的分离,在 Struts 框架的模型部分,控制业务跳转,利用 Hibernate 框架对持久层提供支持,Spring 做管理,管理 struts 和 hibernate。


4.2.1.3、MVC 架构

MVC 层比较有时代意义的就是 SSM 框架,Mybatis 作为 ORM 映射框架来提供数据访问层的服务,Spring 容器统一管理,SpringMVC 完成了逻辑控制到展示层的输出。由于 SpringMVC 的轻量级,Struts 爆出安全漏洞,Mybatis 的简单易学。SSM 框架成为了小型应用首选框架。

4.2.2、SOA 服务化架构设计

4.2.2.1、Web Service

Web Service 技术是 SOA 服务化的一种实现方式,使运行在不同的机器及操作系统上的服务的互相发现和调用成为可能,并且可以通过某种协议来交换数据。我们从上图可以看到每个服务之间是对等的,并且互相是解藕的,通过 WSDL 定义的服务发现接口进行访问,并通过 SOAP 协议进行通信。SOAP 协议通常是一种在 HTTP 或者 HTTPS 通道上传输 XML 数据来实现的协议,但是每个服务都要依赖中心化 Web Service 目录来发现已经注册的服务。而我们通常意义上看到的 dubbo 框架是不是很相像,registry 模块(Web Service 目录),consumer 模块(Web Service 1),provider 模块(Web Service 2 和 3)。

图片来源于 dubbo 官网

4.2.2.2、ESB



ESB 全称为 Enterprise Service Bus,即企业服务总线。它是传统中间件技术与 XML、Web 服务等技术结合的产物。ESB 提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。ESB 的出现改变了传统的软件架构,可以提供比传统中间件产品更为廉价的解决方案,同时它还可以消除不同应用之间的技术差异,让不同的应用服务器协调运作,实现了不同服务之间的通信与整合。从功能上看,ESB 提供了事件驱动和文档导向的处理模式,以及分布式的运行管理机制,它支持基于内容的路由和过滤,具备了复杂数据的传输能力,并可以提供一系列的标准接口。


4.2.3、微服务化架构设计

SOA 与微服务架构实现的区别

SOA 实现:

  • 企业级,自顶向下开展实施

  • 服务由多个子系统组成,粒度大

  • 企业服务总线,集中式的服务架构

  • 集成方式复杂(WS/ESB/SOAP)

  • 单块架构,相互依赖,部署复杂

微服务架构实现:

  • 团队级,自底向上开展实施

  • 一个系统拆分多个服务,粒度细

  • 无集中式总线,松散的服务架构

  • 集成方式简单(HTTP/REST/JSON)

  • 服务能独立部署


为什么微服务推行?

相比传统 SOA 的定义,微服务是其中的一个子集。而对于实现方式来看,他是一种灵活性极高的可实施性,可扩展性极高的互联网发展趋势的实践。

微服务架构设计图

简单举个例子,本身单体应用用户系统,服务化改造以后根据不同职能模块进行子系统拆分,提供不同的服务。

五、感悟

  • 架构的演变是基于不同场景下的实践,因为痛点的驱动不断完善的。

  • 产品的演变是基于不同用户的诉求,因为痛点的驱动不断优化的。

  • 思考:人的成长演变是基于什么呢?


发布于: 2020 年 07 月 07 日阅读数: 139
用户头像

小胜靠智,大胜靠德 2019.06.27 加入

历经创业、京东、腾讯、滴滴公司,希望能够有些东西一起分享。公众号:小诚信驿站,微信/CSDN搜索:wolf_love666

评论

发布
暂无评论
架构设计篇之面向对象设计