设计模式——结构型模式(三)

Composite(组合模式)

目标

将对象组合成树形结构以表示“部分-整体”的层次结构,该模式是的用户对单个对象以及组合对象的使用具有一致性。

结构

通用结构图

一个组合模式中有着容器以及实现对象,但是它们都是一个Component的各子类。

Android中View层次图

Android中的View,可以作为一种容器来存放其他的View,也可以自己作为一个单独的View。

weiter lesen

设计模式——结构型模式(二)

Bridge(桥接模式)

目标

将抽象部分与他的实现部分分离,使它们都可以独立地变化。

结构

结构图

桥接模式在抽象父类中存储一个抽象的Implementor指针,然后在子类实现的时候传递一个ConcreteImplementor。Client直接调用抽象父类的相应方法即可。

协作

时序图

Client在创建了一个具体的功能实现类对象,将这个功能传递给父类,这样就获得一个能够实现功能的操作类。

weiter lesen

设计模式——结构型模式(一)

Adapter(适配器模式)

目标

将一个类的接口转换成客户所希望的另一个接口,范围从单纯的改变接口的名称直到适配、甚至添加额外的方法以便满足完全没有联系的接口方法。

结构

对象适配器结构图

对象适配器依赖于对象的组合,主要是依靠Adapter类的代理,将对于Adapter的requset与special request转发到Target类与Adaptee中去。

类适配器结构图

类适配器依赖于多重继承(java中即是接口),将相应需要提供的方法加在Target类上。

协作

时序图

如图所示,Client类调用Adapter类上的某些方法,以实现相应的request或者是specailRequset方法。

weiter lesen

设计模式——创建型模式(四)

Singletion(单例模式)

目标

保证一个类只有一个实例,并且提供一个访问它的全局访问点。

结构

结构图

图中反映的是所谓懒汉式单例模式——但需要这样一个对象的时候才开始创建这样的一个对象。相反,还有一种勤劳单例模式,当这个类被加载的时候就会创建这样一个单例对象。

协作

时序图

  1. 当用户需要的时候,向类请求一个对象;

  2. 类如果没有创建这个单例对象,就会创建这个对象并且传递回来,如果类已经创建了这个对象,那么就直接简单地将对象传递回来即可。

weiter lesen

设计模式——创建型模式(二)

Builder(生成器)

目标

将一个较为复杂的对象的构建与表示分离,并且能够在多个构建过程之后构建出不同的表示。

结构

结构图

对于一个Builder它将会把生产过程中的产物放在自己这里,按照Director的调用方法的顺序来执行生产,最后有一个返回产物的方法。

协作

时序图

  1. 客户创建一个Director对象,并且配置相应的Builder;

  2. Builder处理Director的请求,将部件添加到产品中;

  3. 客户从Builder中检索获得产品。

weiter lesen

设计模式——创建型模式(一)

Abstract Factory(抽象工厂)

目标

提供一个无需指定的类而可以创建一系列相关的对象的接口。

结构

抽象工厂

由一个Abstract Factory类派生出多个子类工厂,子类工厂将会提供相应的创建产品的方法。对于客户来说,只需要获得Abstract Factory类中的接口就可以实现各类产品的创建。(与工厂方法有一点区别在抽象工厂一般是生成一系列相互有关系的产品,工厂模式方法一般就是生成某一个产品)

适用情形

  1. 一个系统要独立于它的产品的创建、组合和表示时;

  2. 一个系统要由多个产品系列的一个来配置时;

  3. 当你强调一系列相关产品对象的设计以便联合使用的时候;

  4. 当你提供一个产品类库,而只想显示他们的接口而不是实现。

weiter lesen

LeetCode的Easy题(二)

Description

Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST.

Follow up

Could you do that without using any extra space? (Assume that the implicit stack space incurred due to recursion does not count).

Thinking

这个题是一个求众数的题目,对于一个排序好的数组来说,如果不用hash表来做的话,一个很容易想到的方法就是先遍历一次,将众数这个数出现的次数记录下来,然后第二次遍历的时候把相应的众数纪录下来就行。不过这里要注意到想要让BST能够按照一个排序数组遍历下来的话,需要中序遍历(一开始就没注意到这个问题……)

weiter lesen

Java中的序列化(Serializable)

简介

在做寒假的数据结构实验中,实验要求自己实现链表,这当然是非常简单的事情。但是在序列化存储的时候,发现如果简单地在链表类后面加上implements Serializable会出现StachOverFlow的问题。思考一番,一个链表在存储的时候会将自己后面的结点存储下来,然后再对下一个结点采取同样的处理,是会发生爆栈的问题。那究竟怎样处理这个问题呢?

关键字transient

通过阅读Java8中LinkedList的源码,能看到有一个以前没怎么见过的一个关键词transient。

transient是一个只能用来修饰实现了Serializable的变量或者基本数据类型的关键字,它表示被修饰的关键字将不会在序列化过程之中被序列化进去。

weiter lesen

LeetCode的Easy题(一)

Description

Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.

Example

Given a = 1 and b = 2, return 3.

Thinking

一开始还以为是一个a+b question来作为测试的,仔细一看之后发现还有一些些意思的。很显然是要用位运算的组合来得到答案,不过具体要有哪些操作,只能让我们试一试才知道。

比如说:10001 与 101

  1. 10001 ^ 101 = 10100 xor运算之后发现,得到的式子恰好是两个数在不考虑进位情况下的加法运算(同时也是在不考虑借位情况下的减法运算);
  2. 10001 & 101 = 00001 and运算会让两个1变成1,当然这是我们加法中进位的标志,也是进的那个1,所以只需要左移一位就可以得到需要进位的值;
  3. 再用相同的方法递归的将上面两个加起来,直到进位是0就可以了。

Code

1
2
3
4
5
6
7
8
private int getSum(int a, int b) {
if(b == 0){
return a;
}
int sum = a ^ b;
int carry = (a & b) << 1;
return getSum(sum, carry);
}

weiter lesen


Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2018 Alex's Blog All Rights Reserved.

Yifeng Tang hält Urheberrechtsansprüche.