常用设计模式的简单描述

这篇文章主要介绍一些常用的设计模式,寄希望通过简单的几句代码能够一眼看出该设计模式的本质和精髓。(下面的编程语言为Java语言伪代码)


1. 观察者模式

现实例子:找工作过程中,当多个应聘者想跟踪一家单位招聘信息的变化,无需饭不吃、觉不睡时时刻刻的关注着,只需要把你的简历投递过去,把邮箱告诉人家单位就行了,招聘信息有变化时会主动告诉你的,在这个期间,你该吃饭的吃饭、该睡觉的睡觉。

主题(如招聘单位)

public interface Subject {
	void addObserver(Observer o);
	void deleteObserver(Observer o);
	void notifyObservers();
}
观察者应聘学生)

public interface Observer {
	void seekEmail();
}
具体主题腾讯公司)

public class TengXun implements Subject {

	@Override
	public void addObserver(Observer o) { //应聘者发送邮件了
		list.add(o);
	}

	@Override
	public void deleteObserver(Observer o) { //删除邮件
		list.delete(o);
	}

	@Override
	public void notifyObservers() { //通知所有求职者看Email
		for(int i=0; i<list.size(); i++) {
			list.get(i).seekEmail();
		}
	}
}
主题观察者李四)

public class UniversityStudent implements Observer {
	@Override
	public void seekEmail() {
		doSomething();
	}
}

2. 装饰模式

具体例子:JDK中的java.io包中的类就使用了装饰模式,如Reader是一个抽象类,是字符输入流,相当于装饰模式中的抽象组件(Component);FileReader类相当于装饰模式中的具体组件(ConcreteComponent);而BufferedReader相当于装饰模式中的装饰(Decorator)。

抽象组件(如java.io.Reader)

public abstract class Bird {
	public abstract int fly();
}
具体组件(如java.io.FileReader)

public class Sparrow extends Bird {
	@Override
	public int fly() {
		return 100; //飞100米
	}
}
装饰

装饰不但要继承抽象组件,而且内部还有一个抽象组件的成员变量

public abstract class Decorator extends Bird {
	//装饰不但要继承抽象组件,而且内部还有一个抽象组件的成员变量
	Bird bird;

	public Decorator() {}
	public Decorator(Bird bird) {
		super();
		this.bird = bird;
	}
}
具体装饰 (如java.io.BufferedReader)

public class SparrowDecorator extends Decorator {
	public SparrowDecorator(Bird sparrow) {
		super(sparrow);
	}

	@Override
	public int fly() {
		return bird.fly() + 50; //多飞50米
	}
}

测试运行

下面例子中,“小鸟”被装饰了两次,从可以飞100米,到可以飞150米,到可以飞200米。

public class Application {
	public void needBird(Bird bird) {
		int flyDis = bird.fly();
		System.out.println("这只鸟可以飞 " + flyDis + " 米");
	}
	
	public static void main(String[] args) {
		Application app = new Application();
		Bird sparrow = new Sparrow();
		Bird sparrowDec1 = new SparrowDecorator(sparrow); //装饰了一次
		Bird sparrowDec2 = new SparrowDecorator(sparrowDec1); //把装饰又装饰了一次
		app.needBird(sparrowDec1);
		app.needBird(sparrowDec2);
	}
}

运行结果如下:



3. 适配器模式



4. 工厂方法模式

具体实例:Java集合中有一个接口Collection,该接口中的iterator()方法就使用了工厂方法。Collection的实现类比如ArrayList和LinkedList中都有不同的关于Iterator对象的生成方法。按照工厂模式角色的划分,Iterator接口是抽象产品角色;Collection接口是构造者;ArrayList、LinkedList等是具体构造者;ArrayList、LinkedList中的的具体Iterator类就是具体产品。

抽象产品(如java.util.Iterator)

public abstract class PenCore { //抽象产品:笔芯
	String color;
	public abstract void writeWord(String s);
}
抽象构造者(如java.util.Collection)

public abstract class BallPen { //抽象构造者:圆珠笔
	public BallPen() {
		System.out.println("生产了有" + getPenCore() + "笔芯的笔");
	}
	public abstract PenCore getPenCore();
}
具体产品(如java.util.Iterator的具体实现类)

下面有两个具体产品:红笔芯、蓝笔芯。

红笔芯:

public class RedPenCore extends PenCore {
	public RedPenCore() {
		color = "红色";
	}
	@Override
	public void writeWord(String s) {
		System.out.println("写" + color + "颜色的字:" + s);
	}
}
蓝笔芯:

public class BluePenCore extends PenCore {
	public BluePenCore() {
		color = "蓝色";
	}
	@Override
	public void writeWord(String s) {
		System.out.println("写" + color + "颜色的字:" + s);
	}
}
具体构造者(如java.util.ArrayList、java.util.LinkedList)

下面有两个具体构造者:红圆珠笔、蓝圆珠笔。

红圆珠笔:

public class RedBallPen extends BallPen {
	@Override
	public PenCore getPenCore() {
		return new RedPenCore();
	}
}
蓝圆珠笔:
public class BlueBallPen extends BallPen {
	@Override
	public PenCore getPenCore() {
		return new BluePenCore();
	}
}

5. 抽象工厂模式



6. 单例模式

现实实例:对于一个衣服工厂,可能生产很多衣服,但是工厂对象只需要一个,因此对于工厂可使用单例模式。当系统只需要某个类有一个实例时就可以使用单例模式。

单例模式需要保证两件事:1 提供一个单例对象给别人;2 阻止其他开发人员创建新的对象。

单例模式的Java实现如下:

public class Factory {
	private static Factory instance; //唯一的实例
	private Factory() { //私有的构造方法
	}
	
	public Factory getInstance() { //获取唯一的对象
		if(instance == null)
			instance = new Factory();
		return instance;
	}
}
多线程改进

对于上述代码,如果有多线程的话,可能创建的就不止一个对象了,因此需要加锁,如下:

public class Factory {
	private static Factory instance; //唯一的实例
	private static Object lockObj = Factory.class; //用于加锁的
	
	private Factory() { //私有的构造方法
	}
	
	public Factory getInstance() { //获取唯一的对象
		synchronized (lockObj) {
			if(instance == null)
				instance = new Factory();
			return instance;
		}
	}
}

7. 享元模式



8. 接桥模式


9. 代理模式

现实实例:用户在跟公司老板联系时必须先联系老板的秘书,此时秘书就相当于老板的代理。

代理分为静态代理和动态代理,其中动态代理的例子可参见: JDK和CGLib两种方式实现动态代理模式

下面是静态代理的代码实现。

抽象主题

public interface Geometry {
	double getArea();
}
具体模板

public class Triangle implements Geometry {
	double sideA, sideB, sideC;

	public Triangle(double sideA, double sideB, double sideC) {
		this.sideA = sideA;
		this.sideB = sideB;
		this.sideC = sideC;
	}

	@Override
	public double getArea() {
		double p = (sideA + sideB + sideC) / 2.0;
		return Math.sqrt(p * (p-sideA) * (p-sideB) * (p-sideC));
	}
}
代理

public class TriangleProxy implements Geometry {
	double sideA, sideB, sideC;

	public void setABC(double a, double b, double c) {
		this.sideA = a;
		this.sideB = b;
		this.sideC = c;
	}

	@Override
	public double getArea() {
		if(sideA+sideB>sideC || sideA+sideC>sideB || sideB+sideC>sideA) {
			return new Triangle(sideA, sideB, sideC).getArea(); //相当于秘书叫老板
		}
		return -1;
	}
}
测试运行

public class Application {
	public static void main(String[] args) {
		double a = 3, b = 4, c = 5;
		TriangleProxy triProxy = new TriangleProxy();
		triProxy.setABC(a, b, c);
		double area = triProxy.getArea();
		System.out.println("面积是:" + area);
	}
}
运行结果如下:



有待完善。转载请注明出处。


参考文献

耿祥义,Java设计模式.清华大学出版社.

John Metsker,Designs Patterns In Java. 电子工业出版社.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值