写在前面

这个专栏记录学习设计模式的一些笔记,相关代码在GitHub

面向对象基础

字段和属性

变量私有的叫字段,公有的是属性,那么对于方法而言,同样也就有私有方法和公有方法了,一般无需要对外界公开的方法都应该设置其修饰符为 private(私有)。这才有利于”封装“

继承的使用场景

对象的继承代表了一种”is-a“的关系,如果两个对象A和B,可以描述为”B是A“,则表明B可以继承A。”猫是哺乳动物“,就说明了猫与哺乳动物之间继承与被继承的关系。

抽象类和接口的区别

从表象上来说,抽象类可以给出一些成员的实现,接口却不包含成员的实现,抽象类的抽象成员可被子类部分实现,接口的成员需要实现类完全实现,一个类只能继承一个抽象类,但可实现多个接口等等。但这些都是从两者的形态上去区分的。还有三点是能帮助我们去区分抽象类和接口的。

**第一,类是对对象的抽象;抽象类是对类的抽象;接口是对行为的抽象。**接口是对类的局部(行为)进行的抽象,而抽象类是对类整体(字段、属性、方法〉的抽象。如果只关注行为抽象,那么也可以认为接口就是抽象类。总之,不论是接口、抽象类、类甚至对象,都是在不同层次、不同角度进行抽象的结果,它们的共性就是抽象。

第二,如果行为跨越不同类的对象,可使用接口;对于一些相似的类对象,用继承抽象类。

**第三,从设计角度讲,抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知子类的存在,方法如何实现还不确认,预先定义。**这里说明的是抽象类和接口设计的思维过程。先是有一个Cat类,然后再有一个 Dog类,观察后发现它们有类似之处,于是泛化出 Animal类,通过重构改善既有代码的设计

ArrayList

可以根据使用大小按需动态增加,不用受事先设置其大小的控制。可以随意地添加、插入或移除某一范围元素,比数组方便。但是,ArrayList不是类型安全的。

ArrayList对于存放值类型的数据,比如 int、string型或者结构struct 的数据,用ArrayList就意味着都需要将值类型装箱为Object对象,使用集合元素时,还需要执行拆箱操作,这就带来了很大的性能损耗。

装箱是把值类型打包到Objeet 引用类型的一个实例中,比如整型变量i被“装箱”并赋值给对象o。

1
2
int i = 123;
object o = (object) i; //boxing

拆箱是指从对象中提取值类型。此例中对象o拆箱并将其赋值给整型变量i

1
2
o = 123;
i = (int) o; //unboxing

相对于简单的赋值而言,装箱和拆箱过程需要进行大量的计算。对值类型进行装箱时,必须分配并构造一个全新的对象。其次,拆箱所需的强制转换也需要进行大量的计算。而 ArrayList集合在使用值类型数据时,其实就是在不断地做装箱和拆箱的工作。

泛型

泛型是具有占位符(类型参数〉的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。泛型集合类可以将类型参数用作它所存储的对象的类型的占位符;类型参数作为其字段的类型和其方法的参数类型出现。

通常情况下,都建议使用泛型集合,因为这样可以获得类型安全的直接优点而不需要从基集合类型派生并实现类型特定的成员。此外,如果集合元素为值类型,泛型集合类型的性能通常优于对应的非泛型集合类型(并优于从非泛型基集合类型派生的类型),因为使用泛型时不必对元素进行装箱。

委托与事件

委托是对函数的封装,可以当作给方法的特征指定一个名称。而事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程。

委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。

Java实现:

UML类图

”动物“矩形框,它就代表一个类(Class)。类图分三层,第一层显示类的名称,如果是抽象类,则就用斜体显示。第二层是类的特性,通常就是字段和属性。第三层是类的操作,通常是方法或行为。‘+’表示public,‘-’表示private,‘#’表示protected。

image-20210818143456545

接口

image-20210818143711601

继承

继承关系用空心三角形+实线来表示

image-20210818143819609

实现接口

实现接口用空心三角形+虚线来表示

image-20210818143927965

关联

当一个类”知道“另一个类时,可以用关联(association)。关联关系用实线箭头来表示。

image-20210818144208128

聚合

聚合(Aggregation)表示一种弱的”拥有"关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。聚合关系用空心的菱形+实线箭头来表示。

image-20210818144339999

image-20210818144348634

合成

合成(Composition,也有翻译成“组合”的)是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。在这里鸟和其翅膀就是合成(组合)关系,因为它们是部分和整体的关系,并且翅膀和鸟的生命周期是相同的。合成关系用实心的菱形+实线箭头来表示。另外,合成关系的连线两端还有一个数字”1“和数字”2“,这被称为基数。表明这一端的类可以有几个实例,很显然,一个鸟应该有两只翅膀。如果一个类可能有无数个实例,则就用”n“来表示。关联关系、聚合关系也可以有基数的。

image-20210818144744450

依赖关系

动物几大特征,比如有新陈代谢,能繁殖。而动物要有生命力,需要氧气、水以及食物等。也就是说,动物依赖于氧气和水。他们之间是依赖关系(Dependency),用虚线箭头来表示。

image-20210818144819859

image-20210818144827964

设计模式分类

创建型模式

工厂方法

抽象工厂

生成器(亦称建造者模式)

原型

单例

结构型模式

适配器

桥接

组合

装饰

外观

享元

代理

行为模式

责任链

命令

迭代器

中介者

备忘录

观察者

状态

策略

模板方法

访问者