软件架构概念介绍(二)

本文是 《软件架构概念介绍(一)》 的下半部分,原文某些概念使用了.NET讲解,由于对.NET不熟悉,可能理解的不是很透彻,整体读下来,个人觉得软件架构概念还是很复杂的,后面会用Python或PHP再进行详细的学习,修炼内功,什么时候都不晚。

7:关联(Association)

描述两个类之间关系相对通用的术语是关联,而聚合和组合是相对特殊的概念。

关联表示两个类之间是 has-a 关系,类之间没有特定的所有权,它只是连接两个类。

聚合(Aggregation)是一种弱类型的关联,两个类之间有部分的所有权。 使用术语 uses 来暗示弱 has-a 关系。 比如一个学校某个部门聚合了教师,教师实际上属于很多部门,如果某个部门不存在了,教师还存在。

组合(Composition )是一种强类型的关联,某个类拥有另外一个类完整的所有权。一般使用 owns 来暗示强关系的 has-a ,比如学校某个部门教授一门课程,如果这个部门消失了,那么课程也就没了。

总体来说聚合是一种特殊的关联,而组合是一种特殊的聚合,Association->Aggregation->Composition。

8:抽象和泛化

抽象强调理念、属性而不是细节,抽象的重要性来源于其可以隐藏不相关细节,以及通过名称引用对象的能力。

抽象在项目中至关重要,强调对象是什么或做什么,并不强调如何工作的,它是管理大型程序复杂性的主要手段。

抽象是通过隐藏不相关细节降低复杂性,泛化是通过替换多个entities(它们拥有相同的结构,且执行类似的功能)降低复杂性的。泛化通过拥有更大领域对象(相同类型或不同类型)来扩展应用程序,编程语言通过变量,参数化,泛型和多态性提供泛化。它强调对象之间的相似性,因此泛化通过将个体汇总到组管理复杂性,并能提供一个representative(找出组中任何一个个体)。

抽象和泛化经常一起使用,Abstracts are generalized through parameterization to provide greater utility。在参数化中,entity中一个或多个部分被替换成一个指向entity的新名称,新名称就是parameter,当parameterized abstract被调用的时候,将绑定 parameterargument

9:什么是抽象类

一个类如果前面有abstract关键字,那么它就是抽象类,抽象类不能实例化,它只能是其它类的超类。

抽象类是一个概念,子类必须实现抽象类,一个类只能继承于一个抽象类(但能实现多个接口)。

一个实现类必须覆盖(override)所有申明为abstract的methods/properties,同时也必须覆盖所有虚methods/properties。

抽象类是实现框架非常好的一种方法。

10:接口

接口通过定义结构,拆分了具体实现,当你需要实现更加的通用(实现可改变),那么接口非常有用,除此之外如果实现修改非常频繁,接口也非常有用。

题外话,有些人说用接口的形式定义所有类,但我不推荐这种方式,多态和接口应该是一种面向对象编程思想,而不是语言属性,比如Python中就没有原生支持多态和接口,这说明什么?

接口用来定义一个通用模版,然后一个或多个抽象类去定义这个接口的局部实现,接口仅仅指定方法定义(隐式公开或抽象),包含属性properties(隐示公开或抽象)。

接口使用keyword关键字申明,接口和抽象类一样不能实例化。

假如一个类实现一个接口,但没有定义(不是申明)所有的方法,那么它就是一个抽象类,所有的方法定义必须由抽象类的子类来扩展,除此之外接口可以从其他接口继承。

11:接口和类的区别

在某些语言中,一个类能够实现一个接口,也能够实现多个接口,当类实现一个接口时,这个类的对象就封装在这个接口内部,比如MyLogger是一个类,同时它实现了ILogger接口,那它可以这样写:

ILogger log = new MyLogger();

从概念上来说,接口和类是完全不同的,从理论上来说,类强调封装的概念,而接口强调抽象的概念(隐藏实现细节),它们之间有着明显的不同,因此比较它们非常困难且没有意义,而接口和抽象类之间可以进行比较(见下面)。

12:抽象类和接口之间的区别

抽几个觉得重要的说明:

  • 接口没有任何实现,但它们必须被实现;抽象类的方法可以有默认的实现,也可以扩展,抽象类的方法可以独立于子类运行。
  • 抽象类的方法如果也定义为抽象,那么在抽象类中就不能被实现。
  • 接口能够继承一个或多个接口;抽象类能够实现一个或多个接口,但它们仅能继承一个类。
  • 抽象类必须覆盖所有的抽象方法,也必须覆盖所有的虚拟方法。
  • 但实现发生变化的时候,这时候可以选择使用接口;抽象类可以作为基类实现一些默认的行为。
  • 接口使实现可以互换(interchangeable),接口通过隐藏实现细节从而提供安全性。
  • 当实现框架的时候,可以选择抽象类。
  • 如果想产生继承层次结构,那么抽象类是非常好的一种方法。

抽象类让你定义一些行为,它强迫你的子类提供其他的行为,举个例子,假如你有一个应用程序框架,一个抽象类用来给服务提供默认的实现和一些必须的模块,比如事件记录和消息处理,这种方法允许开发者在这个框架的指导下开发应用程序。

然后,在具体实践中,当遇到一些应用程序特定功能时,只有你的程序能执行,比如启动或暂停工作。抽象类能够定义一些虚拟的启动或暂停方法,基类知道它需要这些方法,但一个抽象类让你的类承认它不知道如何执行这些动作,它只知道必须启动这些动作,当到了启动的时候,抽象类能够调用启动方法,但基类调用这个方法的时候,它能够执行子类定义的方法。

13:继承

我们知道抽象和泛化之间关系紧密,继承和特化同样如此,将这两个概念和泛化放在一起讨论很重要,这样能够更好的明白并减低复杂性。

通过扩展现有类来创建新类的能力称为继承。

现实世界中对象之间最重要的关系是特化(specialization),它能表示为 is-a 的关系。当说狗是一种动物,表示狗是动物的一种特化,它有动物的所有特征,但它也特化出一些家犬特有的特征;猫也是哺乳动物,它和够一样分享一些相同的特征,但它也具有一些猫的特殊特征。

特化和泛化之间的关系是相互倒立且分层的,泛化的另外一面就是泛化,哺乳动物在猫和狗之间泛化了一些特征,但它们也特化了一些特殊的特征。

举个例子,IOException和SecurityException是Exception的子类型,它们有Exception所有的特征和行为,这表示IOException是Exception的一种特化,SecurityException也是一种Exception,我们希望它和IOException一样共享Exception所有特征。但IOException和SecurityException也特化了Exception,拥有自己独特的特征。

在OOP中,特化关系使用称为继承的原则实现,这是最常用,也是最自然,最广泛被接收的特化实现方式。

14:多态

多态是一种通用术语,表示“多种形状”,确切的说多种不同型态的事物能够执行相同的操作。

有时我认为理解面向对象编程非常困难,因为它们有四个主要的概念,同时每个概念之间关系很密切。一次我们必须小心的独立理解每个概念,同时明白和其他概念之间的关系。

在OOP中,多态有多种不同的技术实现,分别是方法重载(overloading),操作符重载,方法覆盖(overriding)。

15:方法重载

方法重载可以使用相同的名字定义多个方法,比如:

public class MyLogger
{
    public void LogError(Exception e)
    {
        // Implementation goes here
    }

    public bool LogError(Exception e, string message)
    {
        // Implementation goes here
    }
}

16:操作符重载

它是多态的一种特殊情况,某些运算符(比如+,-,==)称为多态函数,因此具有不同的行为(具体取决于其参数的类型)。

17:方法覆盖

方法重写是一种语言功能,它允许子类覆盖超类已经实现的方法。

一个子类可以指定它自己的实现,但需要和超类具有相同的signature,这意味着当重写方法时,子类的方法必须具有与超类具有相同的名称和参数列表。

18:Use Case,Class Diagram,Package Diagram,Sequence Diagram

这些都是UML中的概念,后续需要看一些专业的资料才能掌握,目前看了这篇文章后,完全无感。

19:二层和三层架构

二层架构已经很古老了,三层架构其实也已经不适合目前的技术潮流了,但仍然有一定的代表性,包含三个部分:

  • 表示层/Web服务器:用户接口,用于显示/接收数据。
  • 应用逻辑/业务逻辑/事务层/应用服务器:数据校验,业务/应用程序进行具体的操作。
  • 数据层/数据库服务器:对数据库进行连接,存储,操作。

20:MVC架构

Model-View-Controller (MVC)架构拆分domain,presentation,actions三种模型到三个独立的类中。

不幸的是,这种模式的普及导致了一些错误的用法,每种技术(PHP,.NET)都有自己的方式定义它,从而很难理解。尤其“控制器”这个术语在不同的上下文中表示不同的事物。

下面这个是.NET中的描述方式:

  • Model:DataSet and typed DataSet (some times business object, object collection, XML, etc.) are the most common uses of the model.
  • View: The ASPX and ASCX files generally handle the responsibilities of the view.
  • Controllers: The handling of events or the controlling is usually done in the code-behind class.

21:SOA

面向服务的架构本质上是一组服务,服务之间互相通信,通信可以是简单的数据传输,或者协调两个或多个服务之间的活动,需要一些方法连接这些服务。

SOA用来连接多个系统以提供服务。SOA其实就是微服务的前身。

22:Gang of Four (GoF) Design Patterns

四人帮模式被认为是其他模式的基础,它们被分为三组(Creational, Structural, and Behavioral),好吧,我是记不下来。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章