本系列主要是对自己在阅读《设计模式的艺术》和《Java设计模式》两本书中知识的分类总结。
初探
在工作中,我们多多少少都会感受到设计模式给我的开发带来的好处,以前一直是临时抱佛脚,遇上不懂的了临时搜索一下,没有成为自己的知识体系中的一环。17年初,我立志改善这种情况,经过前辈推荐正在阅读《设计模式的艺术》和《Java设计模式》。为了加强自己的认知,故写出这系列的个人学习笔记。
设计模式
因为这是第一篇所以需要先记录一下设计模式的基础知识。
设计模式的起源
设计模式并不是IT界独有的东西,它起源于建筑学,应用于很多的学科。
GoF将设计模式引入软件工程领域。
设计模式的目的
设计模式的目的是为了解决问题。我个人认为设计模式就是我们经常讲的对于特定问题的最佳实践。我认为对于缺乏经验的人来说设计模式起引导作用(例如我)。而对于经验丰富的人来说设计模式其实只是问题解决方案的一部分。
适配器模式
适配器其实在我们生活中很常见,最常见的就是电源适配器。将220V的电压转换为电器所使用的电压。这种作用的部分就叫做适配器。
我们再回推回编程环境中。在我们开发的过程中最常见的一种情况就是数据库保存的字段和对外接口所用的字段不同。其实这种情况在大多数编程语言中都已经有比较好的成熟的解决方式。但其实这也是一适配方式。
再回归到我们的所要讲的内容。适配器模式主要解决的就是兼容性问题。
先明确几个概念帮助我们理解适配器的核心思想。
- 适配器类(用来包装适配者)
- 适配者类(被适配的类)
- 目标抽象类(外部使用所需的接口)
适配器模式的实现主要通过两种方式:
* 继承自适配者类,实现目标抽象类的接口。
* 继承自目标抽象类,并对适配者类进行引用。
在实际开发中我们第一种方式比较常见:
//Java实现
public interface Book {
String getName();
double getPrice();
}
class BookInfo {
private String name = "设计模式的艺术";
private double price = 99.9;
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
class FirstBook extends BookInfo implements Book {
}
因为Java的单继承特性,这种方式只能适配单个适配者。
像C++一样的多继承语言可以同时适配多个适配者。
在学习I/O的时候,有个叫做过滤器的概念,我觉得这个过滤器也是这个套路。
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(“a.txt”)))
java中使用了这种将类的引用传给包装类来进行多适配者的适配工作。
public class Main {
public static void main(String[] args) {
BookInfo bookInfo = new Book();
System.out.println(bookInfo.getName());
System.out.println(bookInfo.getPrice());
}
}
class BookName {
private String name = "设计模式";
public String getName() {
return name;
}
}
class BookPrice {
private double price = 99.9;
public double getPrice() {
return price;
}
}
interface BookInfo {
String getName();
double getPrice();
}
class Book implements BookInfo{
private BookName bookName;
private BookPrice bookPrice;
public Book(){
this.bookName = new BookName();
this.bookPrice = new BookPrice();
}
@Override
public String getName() {
return bookName.getName();
}
@Override
public double getPrice() {
return bookPrice.getPrice();
}
}
缺省适配器模式
在使用的时候我们不希望把所有的方法都实现一遍。这时就需要缺省的配置。我们可以建立一个缺省适配器的类,对所需的接口进行部分或者全部的缺省实现。这样我们在使用的时候就可以直接继承这个缺省的实现,重载掉我们需要自定义的方法就可以了。