适配器模式 Adapter Pattern
2020-03-04
假设现有一个旧接口,客户端希望使用一种新接口的形式调用它,此时可以利用适配器模式,将旧接口以新接口的形式进行封装。不过如果适配器使用过多,则整个系统会显得混乱,因此最好只在希望避免修改原有代码时使用。 适配器模式一般包括如下角色: Adaptee 原接口 Target 客户端希望调用的接口 Adapter 实现 Target 接口的适配器 适配器模式可分为对象适配器模式和类适配器模式。 …
生成器模式 Builder Pattern
2020-01-29
在设计类时,如果包含或将来可能会包含很多属性,就要重载很多构造方法,不仅设计参数麻烦,调用也比较混乱。 为此可以使用 getter、setter 来逐步构造,但这样构造就分为很多步骤,但这可能会产生其它问题,比如维护者看到一部分代码会认为对象已经构造完毕,而实际上并非如此,使用未完全构造的对象就可能出错。另外这种方法也无法处理 final 字段。 Builder 模式就可以很方便地解决这个问题。 …
策略模式 Strategy Pattern
2020-01-27
在软件开发中,某一功能可以有多种实现,如果把这些实现都放在一个类中,则不利于增加、修改和替换,此时可以把可能频繁变化的逻辑抽象出来,Runnable 就采用了类似的思想。这种设计模式叫策略模式: 定义了一族算法(业务规则) 封装了每个算法 这族的算法可互换代替 策略模式相当于在面向对象层面实现函数式编程,于是对于 Python 等可以把方法作为参数的语言,策略模式就显得没必要了。Java 8 也引入了函数式编程的设计,例如 java.util.function 下的各种接口以及 lambda 表达式。 …
Java 集合框架
2019-04-17
Collection Collection 接口基本可分为三种,List、Set 和 Queue。这些接口有对应实现的抽象类,实体类只需要继承抽象类即可,免去不必要的重复编码。 为什么实体类继承了对应的抽象类,还要实现接口呢?例如: …
在 Java 中使用 Map 计数的几种姿势
2018-06-02
一个老生常谈的问题:在 Java 中,如何使用 Map 给对象计数,例如统计字符串出现的次数? 姿势一:containsKey() Map<String, Integer> map = new HashMap<>(); for (String word : words) { if (map.containsKey(word)) map.put(word, map.get(word) + 1); else map.put(word, 1); } 或者: int count = map.containsKey(word) ? map.get(word) : 0; map.put(word, count + 1); 这是最容易想到的方法,然而这种方法至少有两个问题: Integer 中的 value 声明为 final,无法修改,每次更新均会产生一个新的 Integer 对象 过于频繁且不必要的查表,具体来说,在 map 中不含有 word 的情况下会查两次表,分别是 containsKey()、put() 方法;在含有 word 的情况下会查三次表,分别为 containsKey()、get()、put() 方法 …
工厂模式 Factory Pattern
2017-09-09
工厂模式可分为简单工厂模式 Simple Factory Pattern、工厂方法模式 Factory Method Pattern 和 抽象工厂模式 Abstract Factory Pattern。 …
在 Android Java 核心库 libcore 中打印 Log
2017-08-30
Android Java 核心库中是无法直接使用 android.util.Log 的,添加后编译不通过,因为 framework 中的 Java API 依赖于 Java 核心库。 在 Android 7.0 之前,Java 核心库源码在libcore/luni/下,luni 代表 lang、util、net、io,是 Java 中最常见的包;Android 7.0 中,核心库在libcore/ojluni/下,oj 代表 OpenJDK。 本文简单介绍在核心库中打印 Log 的几种方法。 …
装饰器模式 Decorator Pattern
2017-06-22
在面向对象编程中,要扩展一个类或对象的功能,可以使用继承机制。 举例来说,咖啡店可能会提供拿铁、卡布奇诺、美式咖啡、意式浓缩等供客人选择,我们可以先定义一个 Coffee 类,并在其中声明价格、成分等方法,然后为每种咖啡继承它:Latte、Cappuccino、Americano、Espresso 等,每个类中都实现自己的一套价格、成分信息,这些类都是预先定义好的。 我们可以像这样调用: Coffee coffee = new Latte(); System.out.println("Cost: " + getCost() + "; Ingredients: " + getIngredients()); 然而在遇到有定制化需求的客人时,我们遇到了麻烦。他可能会要求把浓缩咖啡、牛奶、奶油、巧克力、甚至酒等进行组合,混合为一种新的咖啡。这就需要在编译时静态地定义这种新的咖啡类型,而定制咖啡的方式有太多种,为每一种组合都定义一个子类不太现实。 装饰器模式(或装饰模式、修饰模式),是面向对象编程领域中,一种动态地往一个特定对象中添加新的行为的设计模式。装饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。 …