Java的设计模式(一)
什么是设计模式?
设计模式其实是组织代码方式的一种经验,由前人在开发中整理归纳出来。
oo设计原则
在oo设计中应该遵循的几个原则:
- 封装变化。即将需要变化的部分与固定不变的部分隔离开,如抽象类中的抽象方法,要求每个子类去实现,这是变化的部分。
- 多用组合,少用继承。组合即一个对象has其他对象。
- 针对接口编程,不针对具体实现编程。接口在java中指的是超类(Supertype),包括抽象类和接口(interface),具体体现在当需要new以对象时,声明成其父类或接口类型。
- 努力设计出交互对象中的松耦合。松耦合即最大限度的“不了解对方”,只知道对方的接口类型和接口中定义的方法,观察者模式就是很好的例子。
- 对扩展开放,对修改关闭。继承其实也是扩展的一种方式,当需要扩展新类型时,继承父类即可;而对修改关闭,说的是不要改动原来的代码,原来的代码已经组织得很好了,不需要改动。
- 依赖抽象,不要依赖具体类。这条原则我感觉跟“针对接口编程”是一样的,抽象的结果必定是个接口,而依赖抽象,实际就是针对接口编程。
设计模式
- 策略模式。策略模式是指将程序中经常需要变化的行为(称为算法族)封装起来,让这些算法族之间可以相互替换。具体方式是将需要变化的行为独立成一个接口,由子类去实现其变化的功能。而主体则has一个该接口对象。这种组合方式可以使主体的行为可以动态改变,同时避免了继承带来的缺点。例如飞行的行为之于鸭子接口,并不是每种鸭子都会飞的且每种鸭子飞行的姿态不一样,所以将飞行的行为独立出来成为一个接口,由鸭子的具体实现类去实现该接口,而鸭子接口则has飞行接口对象,这时,飞行这一算法族就被独立出来了。同时,我们也可以看到组合对象的好处。
- 观察者模式。观察者模式发生在需要交互的两类对象之间,分别称为主题和观察者。拿卖报举例,主题是报纸的,观察者是阅读者。阅读者希望报纸有了新消息就接到通知。主题中有一个容器保存着它的观
查者对象,当自身状态发生改变时就通知观察者。java库中有observeable这个抽象类,主题要继承这个类。观察者则实现observer这个接口。 - 装饰者模式。装饰者模式是给原材料增加一些新功能。所谓的原材料是指和装饰者拥有同一个超类的具体实现类。层级结构如下图
其中原材料指的是四个具体饮料组件,而装饰者是调料。当中的装饰者都has一个被装饰者的超类指针。这里用到的继承只是为了得到合适的引用类型,让装饰者可以一层套一层地装饰对象。 - 工厂方法模式。工厂,顾名思义,就是生产产品的地方,把生产产品的任务交给某个工厂,不必去关心生产的具体产品类型。要实现工厂方法,首先要有一个创建者。通常是超类,还有就是要有产品
的接口。超类操纵产品接口,留有一个抽象的方法,该方法用来创建具体的产品类型,交由其子类去实现。每一个超类的子类实现该抽象方法时,都要创建一个具体的产品类型。 - 抽象工厂模式。抽象工厂提供了一个接口,用来创建相关的一组相关的产品。抽象工厂模式利用工厂方法作为基础,每个方法创建一个产品,所以能创建多个相关的产品。抽象工厂与工厂方法相比,就是全职和兼职的区别。抽象工厂专门提供接口来生产产品,而工厂方法只是作为子类中的一部分。两者都是交由其子类去创建具体类。
- 单件模式。单件模式是为了确保某个类的对象只有唯一的一个。要实现单件模式,首先将该类的构造器变为私有,并且在该类中保有一个该类的静态变量和返回值是该类型的一个静态方法。静态方法是全局访问点,其他地方想要获得该类的实例就得调用该方法。如下图所示。
但是,这样会在面临多线程时出问题。在多线程时可能会创建出几个不同的对象。要解决这个问题。有三种方法
- 同步。直接在静态方法上加上关键词synchronize。但是会牺牲性能。
- 急切实例化。即在该类中定义静态成员变量时就直接初始化。
- 双重检查加锁。该技巧可以保证只有在第一次创建实例时才会同步。不会对性能造成影响。