设计模式一套被反复使用,多数人知晓的代码设计经验的总结,实现可重用代码,使代码更容易被理解,保证代码可靠性。
总体来说,设计模式分为三大类:
创建型模式(五种):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式(七种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式(十一种):策策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
常见的设计模式介绍:
1、单例模式
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
应用实例: 1、一个党只能有一个书记。 2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。 3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景: 1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
2、工厂模式
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:主要解决接口选择的问题。
何时使用:我们明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
关键代码:创建过程在其子类执行。
3、抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
4、观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
关键代码:在抽象类里有一个 ArrayList 存放观察者们。
//一个很好的单例模式
public class DesignModel1 {
private static DesignModel1 instance;
//把构造器私有化
private DesignModel1(){};
public static DesignModel1 getInstance() {
if(instance ==null) {
synchronized (DesignModel1.class) {
if(instance==null) {
instance = new DesignModel1();
}
}
}
return instance;
}
}
interface Animal{
public void say();
}
class Cat implements Animal{
@Override
public void say() {
System.out.println("I am a cat");
}
}
class Dog implements Animal{
@Override
public void say() {
System.out.println("I am a dog");
}
}
class Factory{
public static Animal getInstance(String className) {
//通过equal方法在确定类的实例
Animal ani = null;
if("cat".equals(className)) {
ani = new Cat();
}
if("dog".equals(className)) {
ani = new Dog();
}
return ani;
}
}
public class DesignModel2 {
public static void main(String[] args) {
Animal a = null; // 定义接口对象
a = Factory.getInstance(args[0]); // 通过工厂获取实例
if (a != null) { // 判断对象是否为空
a.say(); // 调用方法
}
}
}
/**
* 代理模式就是多一个代理类出来,替原对象进行一些操作
* 例如买房子找中介,上法院找律师等等
*/
interface Sourceable1 {
public void method();
}
class Source1 implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
//注意装饰器模式持有的是接口的实例,代理模式持有的是实现类的实例
class Proxy1 implements Sourceable1{
private Source1 source1;
public Proxy1() {
super();
this.source1 = new Source1();
}
//重写Sourceable1的method()方法,并且持有的Source1实现类是实例也进行操作
@Override
public void method() {
before();
source1.method();
after();
}
private void before() {
System.out.println("before proxy!");
}
private void after() {
System.out.println("after proxy!");
}
}
public class DesignModel7 {
public static void main(String[] args) {
Sourceable1 source = new Proxy1();
source.method();
}
}
/**
*适配器模式:一个接口可能有多个的实现方法,但是我们不需继承一个接口全部的实现它
*而是用一个抽象类继承接口,然后我们选择性的继承即可
*
*/
interface Window {// 定义Window窗口接口,表示窗口操作
public void open();// 窗口打开
public void close();// 窗口关闭
public void iconified();// 窗口最小化
public void deiconified();// 窗口恢复
public void activated();// 窗口活动
}
//定义抽象类实现接口,在此类中覆写方法,但是所有的方法体为空
abstract class WindowAdapter implements Window {
public void open() {
};// 窗口打开
public void close() {
};// 窗口关闭
public void iconified() {
};// 窗口最小化
public void deiconified() {
};// 窗口恢复
public void activated() {
};// 窗口活动
}
//子类继承WindowAdapter抽象类,选择性实现需要的方法
class WindowImpl extends WindowAdapter {
public void open() {
System.out.println("窗口打开");// 实现open()方法
}
public void close() {
System.out.println("窗口关闭");// 实现close()方法
}
}
public class DesignModel4 {
public static void main(String args[]) {
Window win = new WindowImpl(); // 实现接口对象
// 调用方法
win.open();
win.close();
}
}
interface Observer{
public void updata();
}
class Observer1 implements Observer{
@Override
public void updata() {
System.out.println("observer1 has received!");
}
}
class Observer2 implements Observer{
@Override
public void updata() {
System.out.println("observer2 has received!");
}
}
interface Subject{
/*增加观察者*/
public void add(Observer observer);
/*删除观察者*/
public void del(Observer observer);
/*通知所有的观察者*/
public void notifyObservers();
/*自身的操作*/
public void operation();
}
abstract class AbstractSubject implements Subject{
private List observers = new ArrayList<>();
@Override
public void add(Observer observer) {
observers.add(observer);
}
@Override
public void del(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
Iterator ite = observers.iterator();
while(ite.hasNext()) {
ite.next().updata();
}
}
}
class MySubject extends AbstractSubject{
@Override
public void operation() {
System.out.println("udpate self");
notifyObservers();
}
}
public class DesignModel8 {
public static void main(String[] args) {
Subject sub = new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.operation();
}
}