设计模式的分类:
设计模式可以分为三大类,分别是创建型设计模式、行为型设计模式以及结构型设计模式。
创建型的设计模式:
单例模式(Singleton)
构建模式(Builder)
原型模式(Prototype)
抽象工厂模式(Abstract Factory)
工厂方法模式(Factory Method)
行为设计模式:
策略模式(Strategy)
状态模式(State)
责任链模式(Chain of Responsibility)
解释器模式(Interpreter)
命令模式(Command)
观察者模式(Observer)
备忘录模式(Memento)
迭代器模式(Iterator)
模板方法模式(Template Method)
访问者模式(Visitor)
中介者模式(Mediator)
结构型设计模式:
装饰者模式(Decorator)
代理模式(Proxy)
组合模式(Composite)
桥连接模式(Bridge)
适配器模式(Adapter)
蝇量模式(Flyweight)
外观模式(Facade)
各种模式的表述:
单例模式(Singleton):确保有且只有一个对象被创建。
抽象工厂模式(Abstract Factory):允许客户创建对象的家族,而无需指定他们的具体类。
工厂方法模式(Factory Method):由子类决定要创建的具体类是哪一个。
装饰者模式(Decorator):包装一个对象,以提供新的行为。
状态模式(State):封装了基于状态的行为,并使用委托在行为之间切换。
迭代器模式(Iterator):在对象的集合之中游走,而不暴露集合的实现。
外观模式(Facade):简化一群类的接口。
策略模式(Strategy):封装可以互换的行为,并使用委托来决定要使用哪一个。
代理模式(Proxy):包装对象,以控制对此对象的访问。
适配器模式(Adapter):封装对象,并提供不同的接口。
观察者模式(Observer):让对象能够在状态改变时被通知。
模板方法模式(Template Method):有子类决定如何实现一个算法中的步骤。
组合模式(Composite):客户用一致的方法处理对象集合和单个对象。
命令模式(Command):封装请求成为对象。
1、装饰模式
装饰模式是对对象功能增强时,平时使用继承的一种替代方案
2. 具体构件
单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
一、懒汉式单例子
Composite模式的类图描述:
Component
树形结构的节点抽象
- 为所有的对象定义统一的接口(公共属性,行为等的定义)
- 提供管理子节点对象的接口方法
- [可选]提供管理父节点对象的接口方法
Leaf
树形结构的叶节点。Component的实现子类
Composite
树形结构的枝节点。Component的实现子类
IFile:File与Folder的共通接口界面。相当于Component。
Folder:目录。目录下面有子目录,文件。相当于Composite。
File:文件。存在于目录之中。相当于Leaf。
Client类:测试类或者说使用类。
代码:
- import java.util.List;
- public class Client {
- public static void main(String[] args) {
- //构造一个树形的文件/目录结构
- Folder rootFolder = new Folder("c://");
- Folder compositeFolder = new Folder("composite");
- rootFolder.addChild(compositeFolder);
- Folder windowsFolder = new Folder("windows");
- rootFolder.addChild(windowsFolder);
- File file = new File("TestComposite.java");
- compositeFolder.addChild(file);
- //从rootFolder访问整个对象群
- printTree(rootFolder);
- }
- private static void printTree(IFile ifile) {
- ifile.printName();
- List <IFile> children = ifile.getChildren();
- for (IFile file:children) {
- if (file instanceof File) {
- System.out.print(" ");
- file.printName();
- } else if (file instanceof Folder) {
- printTree(file);
- }
- }
- }
- }
- interface IFile {
- public void printName();
- public boolean addChild(IFile file);
- public boolean removeChild(IFile file);
- public List<IFile> getChildren();
- }
- class File implements IFile {
- private String name;
- public File(String name) {
- this.name = name;
- }
- public void printName() {
- System.out.println(name);
- }
- public boolean addChild(IFile file) {
- return false;
- }
- public boolean removeChild(IFile file) {
- return false;
- }
- public List<IFile> getChildren() {
- return null;
- }
- }
- class Folder implements IFile {
- private String name;
- private List <IFile> childList;
- public Folder(String name) {
- this.name = name;
- this.childList = new ArrayList<IFile>();
- }
- public void printName() {
- System.out.println(name);
- }
- public boolean addChild(IFile file) {
- return childList.add(file);
- }
- public boolean removeChild(IFile file) {
- return childList.remove(file);
- }
- public List<IFile> getChildren() {
- return childList;
- }
- }
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args) {
//构造一个树形的文件/目录结构
Folder rootFolder = new Folder("c://");
Folder compositeFolder = new Folder("composite");
rootFolder.addChild(compositeFolder);
Folder windowsFolder = new Folder("windows");
rootFolder.addChild(windowsFolder);
File file = new File("TestComposite.java");
compositeFolder.addChild(file);
//从rootFolder访问整个对象群
printTree(rootFolder);
}
private static void printTree(IFile ifile) {
ifile.printName();
List <IFile> children = ifile.getChildren();
for (IFile file:children) {
if (file instanceof File) {
System.out.print(" ");
file.printName();
} else if (file instanceof Folder) {
printTree(file);
}
}
}
}
interface IFile {
public void printName();
public boolean addChild(IFile file);
public boolean removeChild(IFile file);
public List<IFile> getChildren();
}
class File implements IFile {
private String name;
public File(String name) {
this.name = name;
}
public void printName() {
System.out.println(name);
}
public boolean addChild(IFile file) {
return false;
}
public boolean removeChild(IFile file) {
return false;
}
public List<IFile> getChildren() {
return null;
}
}
class Folder implements IFile {
private String name;
private List <IFile> childList;
public Folder(String name) {
this.name = name;
this.childList = new ArrayList<IFile>();
}
public void printName() {
System.out.println(name);
}
public boolean addChild(IFile file) {
return childList.add(file);
}
public boolean removeChild(IFile file) {
return childList.remove(file);
}
public List<IFile> getChildren() {
return childList;
}
}
执行Client,输出结果:
C:/Composite>java Client
c:/
composite
TestComposite.java
windows
C:/Composite>
简单工厂模式
1. 目的
工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。
2 . 简单工厂模式的结构
• 在编码时不能预见需要创建哪一种类的实例。
• 一个类使用它的子类来创建对象。
• 开发人员不希望创建了哪个类的实例以及如何创建实例的信息暴露给外部程序。
抽象工厂模式
1. 抽象工厂模式可以说是简单工厂模式的扩展,它们主要的区别在于需要创建对象的复杂程度上。
在抽象工厂模式中,抽象产品可能是一个或多个,从而构成一个或多个产品族。 在只有一个产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。
2. 抽象工厂模式的结构
3. 一个简单例子
在以下情况下,应当考虑使用抽象工厂模式。
首先,一个系统应当不依赖于产品类实例被创立,组成,和表示的细节。这对于所有形态的工厂模式都是重要的。
其次,这个系统的产品有多于一个的产品族。
第三,同属于同一个产品族的产品是设计成在一起使用的。这一约束必须得在系统的设计中体现出来。
最后,不同的产品以一系列的接口的面貌出现,从而使系统不依赖于接口实现的细节。
其中第二丶第三个条件是我们选用抽象工厂模式而非其它形态的工厂模式的关键性条件。
下面的程序模仿上面的情形,一个随机数产生对象和两个观察者,这两个观察者都在随机数产生对象那里注册了,意思说如果你产生了新的数字,就通知我一声。
结构图:
名称 | 功能说明 |
Observer | 表示观察者的接口,要成为观察者必须实现此接口才行 |
NumberGenerator | 表示产生数值的抽象类 |
RandomNumberGenerator | 产生随机数的类,继承于NumberGenerator |
NumberObserver | 数字观察者,会打印出变化的数字 |
SymbolObserver | 符号观察者,打印N 个符号,打印多少个符号,由接受到的数值确定 |
1.Observer
- package com.pattern.observer;
- public interface Observer {
- public abstract void update(NumberGenerator generator);
- }
package com.pattern.observer;
public interface Observer {
public abstract void update(NumberGenerator generator);
}
2.NumberGenerator
- package com.pattern.observer;
- import java.util.ArrayList;
- import java.util.Iterator;
- /**
- * @project JavaPattern
- * @author sunnylocus
- * @verson 1.0.0
- * @date Aug 27, 2008 1:35:34 PM
- * @description 产生数值的抽象类
- */
- public abstract class NumberGenerator {
- private ArrayList observers = new ArrayList(); //存储Observer
- /** 添加观察者*/
- public void addObserver(Observer observer) {
- observers.add(observer);
- }
- /** 删除观察者*/
- public void delObserver(Observer observer) {
- observers.remove(observer);
- }
- /** 通知所有观察者*/
- public void notifyObservers() {
- Iterator it = observers.iterator();
- while(it.hasNext()) {
- Observer o =(Observer) it.next();
- o.update(this);//this相当于上面提到的邮局名
- }
- }
- public abstract int getNumber();//获取数字
- public abstract void generate();//产生数字
- }
package com.pattern.observer;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @project JavaPattern
* @author sunnylocus
* @verson 1.0.0
* @date Aug 27, 2008 1:35:34 PM
* @description 产生数值的抽象类
*/
public abstract class NumberGenerator {
private ArrayList observers = new ArrayList(); //存储Observer
/** 添加观察者*/
public void addObserver(Observer observer) {
observers.add(observer);
}
/** 删除观察者*/
public void delObserver(Observer observer) {
observers.remove(observer);
}
/** 通知所有观察者*/
public void notifyObservers() {
Iterator it = observers.iterator();
while(it.hasNext()) {
Observer o =(Observer) it.next();
o.update(this);//this相当于上面提到的邮局名
}
}
public abstract int getNumber();//获取数字
public abstract void generate();//产生数字
}
3.RandomNumberGenerator
- package com.pattern.observer;
- import java.util.Random;
- /**
- * @project JavaPattern
- * @author sunnylocus
- * @verson 1.0.0
- * @date Aug 27, 2008 1:48:03 PM
- * @description 用于产生随机数及通知观察者的类
- */
- public class RandomNumberGenerator extends NumberGenerator{
- private Random random = new Random();//随机数产生器
- private int number; //用于存放数字
- public void generate() {
- for(int i=0 ; i < 5; i++) {
- number = random.nextInt(10);//产生10以内的随机数
- notifyObservers(); //有新产生的数字,通知所有注册的观察者
- }
- }
- /** 获得数字*/
- public int getNumber() {
- return number;
- }
- }
package com.pattern.observer;
import java.util.Random;
/**
* @project JavaPattern
* @author sunnylocus
* @verson 1.0.0
* @date Aug 27, 2008 1:48:03 PM
* @description 用于产生随机数及通知观察者的类
*/
public class RandomNumberGenerator extends NumberGenerator{
private Random random = new Random();//随机数产生器
private int number; //用于存放数字
public void generate() {
for(int i=0 ; i < 5; i++) {
number = random.nextInt(10);//产生10以内的随机数
notifyObservers(); //有新产生的数字,通知所有注册的观察者
}
}
/** 获得数字*/
public int getNumber() {
return number;
}
}
4.NumberObserver
- package com.pattern.observer;
- /** 以数字表示观察者的类*/
- public class NumberObserver implements Observer{
- public void update(NumberGenerator generator) {
- System.out.println("NumberObserver:"+ generator.getNumber());
- try {
- Thread.sleep(1000 * 3); //为了能清楚的看到输出,休眠3秒钟。
- }catch(InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
package com.pattern.observer;
/** 以数字表示观察者的类*/
public class NumberObserver implements Observer{
public void update(NumberGenerator generator) {
System.out.println("NumberObserver:"+ generator.getNumber());
try {
Thread.sleep(1000 * 3); //为了能清楚的看到输出,休眠3秒钟。
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
5.SymbolObserver
- package com.pattern.observer;
- /** 以符号表示观察者的类*/
- public class SymbolObserver implements Observer{
- public void update(NumberGenerator generator) {
- System.out.print("SymbolObserver:");
- int count = generator.getNumber();
- for(int i = 0 ; i < count; i ++) {
- System.out.print("*^_^* ");
- }
- System.out.println("");
- try {
- Thread.sleep(1000 * 3);
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- }
- }
package com.pattern.observer;
/** 以符号表示观察者的类*/
public class SymbolObserver implements Observer{
public void update(NumberGenerator generator) {
System.out.print("SymbolObserver:");
int count = generator.getNumber();
for(int i = 0 ; i < count; i ++) {
System.out.print("*^_^* ");
}
System.out.println("");
try {
Thread.sleep(1000 * 3);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
6.Main(测试类)
- package com.pattern.observer;
- public class Main {
- public static void main(String[] args) {
- //实例化数字产生对象
- NumberGenerator generator = new RandomNumberGenerator();
- //实例化观察者
- Observer observer1 = new NumberObserver();
- Observer observer2 = new SymbolObserver();
- //注册观察者
- generator.addObserver(observer1);
- generator.addObserver(observer2);
- generator.generate(); //产生数字
- }
- }
设计思想:
观察者模式定义了对象之间的一对多的依赖关系,当一个对象的状态发生改变时,所有它的依赖对象将被自动通知并更新