设计模式
五种创建型模式
1、工厂模式
2、抽象工厂模式
3、单例模式
4、建造者模式
概述:相比较工厂模式而言,就是建造模式可以一次建造很多个对象,工厂模式一次只能建造一个。
<wiz_code_mirror>
xxxxxxxxxx
15
1
public class Builder {
2
3
private List<Sender> list = new ArrayList<Sender>();
4
5
public void produceMailSender(int count){
6
for(int i=0; i<count; i++){
7
list.add(new MailSender());
8
}
9
}
10
public void produceSmsSender(int count){
11
for(int i=0; i<count; i++){
12
list.add(new SmsSender());
13
}
14
}
15
}
<wiz_code_mirror>
xxxxxxxxxx
7
1
public class Test {
2
3
public static void main(String[] args) {
4
Builder builder = new Builder();
5
builder.produceMailSender(10);
6
}
7
}
5、原型模式
原型模式的思想就是将一个对象作为原型,对其进行复制、克隆产生一个和元对象类似的新对象,在Java中,复制对象就是通过clone()实现的,先创建一个原型类:
<wiz_code_mirror>
xxxxxxxxxx
6
1
public class Prototype implements Cloneable{
2
public Object clone() throws CloneNotSupportedException{
3
Prototype proto = (Prototype)super.clone();
4
return proto;
5
}
6
}
进行实现Cloneable接口,完成克隆,因为Cloneable接口是一个空接口,因此实现类的方法名称可以任意,但是在实现的内部就是必须调用super.clone()方法。
对于对象的复制,主要分为浅复制和深复制两种:
浅复制:将一个对象复制后,基本数据类型的变量会重新创建,而对于引用类型,还是指向原来对象
深复制:当然和浅复制有区别就是完全的复制,一般需要采用流的形式读入当前对象的二进制输入,再写出二进制数据对应的对象。
<wiz_code_mirror>
xxxxxxxxxx
42
1
public class Prototype implements Cloneable,Serializable{
2
private static final long serialVersionUID = 1L;
3
private String string;
4
5
private SerializableObject obj;
6
7
/*浅复制*/
8
public Object clone() throws CloneNotSupportedException{
9
Prototype proto = (Prototype) super.clone();
10
return proto;
11
}
12
13
/*深复制*/
14
public Object deepclone() throws IOException ,ClassNotFoundException{
15
16
/*写入当前对象的二进制流*/
17
ByteArrayOutputStream bos = new ByteArrayOutputStream();
18
ObjectOutputStream oos = new ObjectOutputStream(bos);
19
oos.writeObject(this);
20
21
/*读取二进制流产生的新对象*/
22
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
23
ObjectInputStream ois = new ObjectInputStream(bis);
24
return ois.readObject();
25
}
26
27
public String getString(){
28
return string;
29
}
30
31
public void setString(String string){
32
this.string = string;
33
}
34
35
public SerializableObject getObj(){
36
return obj;
37
}
38
39
public void setObj(SerializableObject obj){
40
this.obj = obj;
41
}
42
}
七种结构模式
适配器模式
对于适配模式可以分为类的适配器模式、对象的适配器模式、接口的适配器模式
类的适配器模式:
<wiz_code_mirror>
xxxxxxxxxx
32
1
public class Source {
2
3
public void method1() {
4
System.out.println("this is original method!");
5
}
6
}
7
8
public interface Targetable {
9
10
/* 与原类中的方法相同 */
11
public void method1();
12
13
/* 新类的方法 */
14
public void method2();
15
}
16
17
public class Adapter extends Source implements Targetable {
18
19
@Override
20
public void method2() {
21
System.out.println("this is the targetable method!");
22
}
23
}
24
25
public class AdapterTest {
26
27
public static void main(String[] args) {
28
Targetable target = new Adapter();
29
target.method1();
30
target.method2();
31
}
32
}
对象的适配
基本思路类的适配是类似的,就是把source类不继承了,而是把source类进行实例,包含在内部。
<wiz_code_mirror>
xxxxxxxxxx
29
1
public class Wrapper implements Targetable {
2
3
private Source source;
4
5
public Wrapper(Source source){
6
super();
7
this.source = source;
8
}
9
@Override
10
public void method2() {
11
System.out.println("this is the targetable method!");
12
}
13
14
@Override
15
public void method1() {
16
source.method1();
17
}
18
}
19
20
测试类:
21
public class AdapterTest {
22
23
public static void main(String[] args) {
24
Source source = new Source();
25
Targetable target = new Wrapper(source);
26
target.method1();
27
target.method2();
28
}
29
}
接口适配
对于接口适配就是,当我们的一个接口中有多个抽象方法时,我们再写该接口的实现时,就必须实现接口的所有方法,这明显比较浪费,也不是我们想要的,最好的办法就是我们再定义一个抽象类去实现那个接口中的方法,进行方法实现可以实现一些空方法,等到我们自己的类继承该抽象类的时候,我们就可以只关注我们需要的方法就可以了。
总结:
类的适配:将一个类转换成另一个新接口的类时,可以使用类的适配器模式,创建新类,继承原有的类,实现新的接口即可。
对象的适配:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个wrapper类,持有原类的一个实例,在wrapper类的方法中,调用实例的方法就行。
接口适配:当不希望实现一个接口中的所有方法,我们可以中间新建要给抽象类,我们就只可以继承抽象类就可以。
<wiz_code_mirror>
xxxxxxxxxx
37
1
public interface Sourceable {
2
public void method();
3
}
4
5
6
public class Source implements Sourceable {
7
8
@Override
9
public void method() {
10
System.out.println("the original method!");
11
}
12
}
13
14
15
public class Decorator implements Sourceable {
16
17
private Sourceable source;
18
19
public Decorator(Sourceable source){
20
super();
21
this.source = source;
22
}
23
@Override
24
public void method() {
25
System.out.println("before decorator!");
26
source.method();
27
System.out.println("after decorator!");
28
}
29
}
30
public class DecoratorTest {
31
32
public static void main(String[] args) {
33
Sourceable source = new Source();
34
Sourceable obj = new Decorator(source);
35
obj.method();
36
}
37
}
装饰器模式的应用场景:
1、需要扩展一个类的功能
2、动态要给对象一个对象增加功能,而且还能动态撤销,
缺点:产生过多相似的对象,不易排出。
装饰模式
首先明白装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例
Source类是被装饰类,Decorator类是一个装饰类,可以为source类动态的添加一些功能。
<wiz_code_mirror>
xxxxxxxxxx
33
1
public interface Sourceable {
2
public void method();
3
}
4
public class Source implements Sourceable {
5
6
@Override
7
public void method() {
8
System.out.println("the original method!");
9
}
10
}
11
public class Decorator implements Sourceable {
12
13
private Sourceable source;
14
15
public Decorator(Sourceable source){
16
super();
17
this.source = source;
18
}
19
@Override
20
public void method() {
21
System.out.println("before decorator!");
22
source.method();
23
System.out.println("after decorator!");
24
}
25
}
26
public class DecoratorTest {
27
28
public static void main(String[] args) {
29
Sourceable source = new Source();
30
Sourceable obj = new Decorator(source);
31
obj.method();
32
}
33
}
应用场景:
1、需要扩展一个类的功能
2、动态的为一个对象增加功能,而且还能动态撤销
代理模式
代理模式和装饰者模式的区别就是代理模式可以直接在内部就创建了source对象,不用到最后调用的时候才创建对象,当然创建对象的时机不同而已。
<wiz_code_mirror>
xxxxxxxxxx
38
1
public interface Sourceable {
2
public void method();
3
}
4
public class Source implements Sourceable {
5
6
@Override
7
public void method() {
8
System.out.println("the original method!");
9
}
10
}
11
public class Proxy implements Sourceable {
12
13
private Source source;
14
public Proxy(){
15
super();
16
this.source = new Source();
17
}
18
@Override
19
public void method() {
20
before();
21
source.method();
22
atfer();
23
}
24
private void atfer() {
25
System.out.println("after proxy!");
26
}
27
private void before() {
28
System.out.println("before proxy!");
29
}
30
}
31
public class ProxyTest {
32
33
public static void main(String[] args) {
34
Sourceable source = new Proxy();
35
source.method();
36
}
37
38
}
应用场景:
1、修改原有的方法来适应,这样违反了“对扩展开放,对修改关闭”的原则
2、采用一个代理类调用原有的方法,并对产生的结果进行控制
外观模式就是把含有相同操作或者一系列操作联动起来,好比计算机的开机和关机,其中开机就包含了CPU,内存,硬盘一起启动。关机包含了CPU,内存,硬盘关闭操作外观模式
有了computer类,他们之间的关系被放在了computer类里,这就起到了解耦,就是外观模式
桥接模式
桥接模式就是把事物和实现具体分开,使他们可以各自独立的变化,桥接的用意就是:将抽象化和实现化解耦,使得二者可以独立变化。像我们常用的JDBC和DriverManager一样,
通过对于Bridge类的调用,实现了对接口Sourceable的实现类SourceSub1和SourceSub2的调用,然后我可以类似的结合JDBC数据的原理,进行理解了。
桥接模式
<wiz_code_mirror>
xxxxxxxxxx
65
1
public class CPU {
2
3
public void startup(){
4
System.out.println("cpu startup!");
5
}
6
7
public void shutdown(){
8
System.out.println("cpu shutdown!");
9
}
10
}
11
public class Memory {
12
13
public void startup(){
14
System.out.println("memory startup!");
15
}
16
17
public void shutdown(){
18
System.out.println("memory shutdown!");
19
}
20
}
21
public class Disk {
22
23
public void startup(){
24
System.out.println("disk startup!");
25
}
26
27
public void shutdown(){
28
System.out.println("disk shutdown!");
29
}
30
}
31
public class Computer {
32
private CPU cpu;
33
private Memory memory;
34
private Disk disk;
35
36
public Computer(){
37
cpu = new CPU();
38
memory = new Memory();
39
disk = new Disk();
40
}
41
42
public void startup(){
43
System.out.println("start the computer!");
44
cpu.startup();
45
memory.startup();
46
disk.startup();
47
System.out.println("start computer finished!");
48
}
49
50
public void shutdown(){
51
System.out.println("begin to close the computer!");
52
cpu.shutdown();
53
memory.shutdown();
54
disk.shutdown();
55
System.out.println("computer closed!");
56
}
57
}
58
public class User {
59
60
public static void main(String[] args) {
61
Computer computer = new Computer();
62
computer.startup();
63
computer.shutdown();
64
}
65
}
<wiz_code_mirror>
xxxxxxxxxx
54
1
public interface Sourceable {
2
public void method();
3
}
4
public class SourceSub1 implements Sourceable {
5
6
@Override
7
public void method() {
8
System.out.println("this is the first sub!");
9
}
10
}
11
public class SourceSub2 implements Sourceable {
12
13
@Override
14
public void method() {
15
System.out.println("this is the second sub!");
16
}
17
}
18
public abstract class Bridge {
19
private Sourceable source;
20
21
public void method(){
22
source.method();
23
}
24
25
public Sourceable getSource() {
26
return source;
27
}
28
29
public void setSource(Sourceable source) {
30
this.source = source;
31
}
32
}
33
public class MyBridge extends Bridge {
34
public void method(){
35
getSource().method();
36
}
37
}
38
public class BridgeTest {
39
40
public static void main(String[] args) {
41
42
Bridge bridge = new MyBridge();
43
44
/*调用第一个对象*/
45
Sourceable source1 = new SourceSub1();
46
bridge.setSource(source1);
47
bridge.method();
48
49
/*调用第二个对象*/
50
Sourceable source2 = new SourceSub2();
51
bridge.setSource(source2);
52
bridge.method();
53
}
54
}
组合模式
组合模式有时又叫做部分-整体模式,在处理形容树形结构的问题时比较方便,例如二叉树、对于菜单的目录结构都是可以,类似于递归一层一层<wiz_code_mirror>
xxxxxxxxxx
61
1
public class TreeNode {
2
3
private String name;
4
private TreeNode parent;
5
private Vector<TreeNode> children = new Vector<TreeNode>();
6
7
public TreeNode(String name){
8
this.name = name;
9
}
10
11
public String getName() {
12
return name;
13
}
14
15
public void setName(String name) {
16
this.name = name;
17
}
18
19
public TreeNode getParent() {
20
return parent;
21
}
22
23
public void setParent(TreeNode parent) {
24
this.parent = parent;
25
}
26
27
//添加孩子节点
28
public void add(TreeNode node){
29
children.add(node);
30
}
31
32
//删除孩子节点
33
public void remove(TreeNode node){
34
children.remove(node);
35
}
36
37
//取得孩子节点
38
public Enumeration<TreeNode> getChildren(){
39
return children.elements();
40
}
41
}
42
43
public class Tree {
44
45
TreeNode root = null;
46
47
public Tree(String name) {
48
root = new TreeNode(name);
49
}
50
51
public static void main(String[] args) {
52
Tree tree = new Tree("A");
53
TreeNode nodeB = new TreeNode("B");
54
TreeNode nodeC = new TreeNode("C");
55
56
nodeB.add(nodeC);
57
tree.root.add(nodeB);
58
System.out.println("build the tree finished!");
59
}
60
}
61
享元模式
享元模式的主要目的就是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。
FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工具需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,就创建一个新的对象,FlyWeight是超类,一提到共享池,我们就很容易联想到java里面的连接池,想想每个连接的特点,我们不难总结出:适用于作共享的一些个对象,他们有一些共有的属性,就拿数据库连接池来说,url、driverClassName、username、password及dbname,这些属性对于每个连接来说都是一样的,所以就适合用享元模式来处理,建一个工厂类,将上述类似属性作为内部数据,其它的作为外部数据,在方法调用时,当做参数传进来,这样就节省了空间,减少了实例的数量。
<wiz_code_mirror>
xxxxxxxxxx
47
1
public class ConnectionPool {
2
3
private Vector<Connection> pool;
4
5
/*公有属性*/
6
private String url = "jdbc:mysql://localhost:3306/test";
7
private String username = "root";
8
private String password = "root";
9
private String driverClassName = "com.mysql.jdbc.Driver";
10
11
private int poolSize = 100;
12
private static ConnectionPool instance = null;
13
Connection conn = null;
14
15
/*构造方法,做一些初始化工作*/
16
private ConnectionPool() {
17
pool = new Vector<Connection>(poolSize);
18
19
for (int i = 0; i < poolSize; i++) {
20
try {
21
Class.forName(driverClassName);
22
conn = DriverManager.getConnection(url, username, password);
23
pool.add(conn);
24
} catch (ClassNotFoundException e) {
25
e.printStackTrace();
26
} catch (SQLException e) {
27
e.printStackTrace();
28
}
29
}
30
}
31
32
/* 返回连接到连接池 */
33
public synchronized void release() {
34
pool.add(conn);
35
}
36
37
/* 返回连接池中的一个数据库连接 */
38
public synchronized Connection getConnection() {
39
if (pool.size() > 0) {
40
Connection conn = pool.get(0);
41
pool.remove(conn);
42
return conn;
43
} else {
44
return null;
45
}
46
}
47
}
行为模式
其中行为模式主要包含:
父类与子类的关系实现:策略模式、模版方法模式、
两个类之间关系:观察者模式、迭代子类模式、责任链模式、命令模式、
类的状态:备忘录模式、状态模式、
通过中间类:访问者模式、中介者模式、解释器模式
策略模式
自己理解就是:声明很多类是指实现同一个接口、继承同一个类,在实现接口中的方法时,调用父类的方法。对于不同的子类实现不同的功能。
ICalculator提供同意的方法、AbstractCalculateor是辅助类,提供辅助方法。
<wiz_code_mirror>
xxxxxxxxxx
50
1
//统一接口
2
public interface ICalculator {
3
public int calculate(String exp);
4
}
5
6
//辅助类
7
public abstract class AbstractCalculator {
8
public int[] split(String exp,String opt){
9
String array[] = exp.split(opt);
10
int arrayInt[] = new int[2];
11
arrayInt[0] = Integer.parsentInt(array[0]);
12
arrayInt[1] = Integer.parsentInt(array[1]);
13
return arrayInt;
14
}
15
}
16
17
//三个实现类
18
public class Plus extends AbstractCalculator implements ICalculator {
19
20
@Override
21
public int calculate(String exp) {
22
int arrayInt[] = split(exp,"\\+");
23
return arrayInt[0]+arrayInt[1];
24
}
25
}
26
public class Minus extends AbstractCalculator implements ICalculator {
27
28
@Override
29
public int calculate(String exp) {
30
int arrayInt[] = split(exp,"-");
31
return arrayInt[0]-arrayInt[1];
32
}
33
}
34
public class Multiply extends AbstractCalculator implements ICalculator {
35
36
@Override
37
public int calculate(String exp) {
38
int arrayInt[] = split(exp,"\\*");
39
return arrayInt[0]*arrayInt[1];
40
}
41
}
42
public class StrategyTest {
43
44
public static void main(String[] args) {
45
String exp = "2+8";
46
ICalculator cal = new Plus();
47
int result = cal.calculate(exp);
48
System.out.println(result);
49
}
50
}
应用场景:策略模式的决定权在用户,系统本身提供不同的算法的实现,新增或者删除算法,对各种算法做封装,因此,策略模式多用在算法决策系统中,外部用户需要决定用哪个算法即可。
模板方法模式
模板模式核心思想:声明一个抽象类,其中包含一个主方法,主方法实现对本类中其他方法的调用,其他的子方法可以为抽象方法或者实现方法,子类继承该抽象父类时,只需重写相关的抽象方法,即可完成调用。
在AbstractCalculator类中定义一个主方法calculate,calculate()调用spilt()等,Plus和Minus分别继承AbstractCalculator类,通过对AbstractCalculator的调用实现对子类的调用 。
<wiz_code_mirror>
xxxxxxxxxx
35
1
public abstract class AbstractCalculator {
2
3
/*主方法,实现对本类其它方法的调用*/
4
public final int calculate(String exp,String opt){
5
int array[] = split(exp,opt);
6
return calculate(array[0],array[1]);
7
}
8
9
/*被子类重写的方法*/
10
abstract public int calculate(int num1,int num2);
11
12
public int[] split(String exp,String opt){
13
String array[] = exp.split(opt);
14
int arrayInt[] = new int[2];
15
arrayInt[0] = Integer.parseInt(array[0]);
16
arrayInt[1] = Integer.parseInt(array[1]);
17
return arrayInt;
18
}
19
}
20
public class Plus extends AbstractCalculator {
21
22
@Override
23
public int calculate(int num1,int num2) {
24
return num1 + num2;
25
}
26
}
27
public class StrategyTest {
28
29
public static void main(String[] args) {
30
String exp = "8+8";
31
AbstractCalculator cal = new Plus();
32
int result = cal.calculate(exp, "\\+");
33
System.out.println(result);
34
}
35
}
观察者模式
在观察者模式中自己理解了一个,当一个抽象类去实现一个还有很多方法的接口的时候,此时自己原以为抽象类应该全部的实现接口里面的方法,但是实际上可以不用全部实现,可以交给去继承这个抽象类的子类来实现。
在观察者模式中,整体结构中,主要是继承抽象类的子类去实现相关关键操作,或者调用父类中的方法,然后最后的test中声明时声明为接口,但实际指向子类的对象,进行add。remove操作。主要的内在含义就是当依赖的相关方法,当他发生变化时,我们就可以及时的收到通知,不用修改代码。
MySubject类就是我们的主对象,Observer1和Observer2是依赖于MySubject的对象,当MySubject变化时,Observer1和Observer2必然变化。AbstractSubject类中定义着需要监控的对象列表,可以对其进行修改:增加或删除被监控对象,且当MySubject变化时,负责通知在列表内存在的对象。
<wiz_code_mirror>
xxxxxxxxxx
68
1
public interface Observer {
2
public void update();
3
}
4
public class Observer1 implements Observer {
5
6
7
public void update() {
8
System.out.println("observer1 has received!");
9
}
10
}
11
public class Observer2 implements Observer {
12
13
14
public void update() {
15
System.out.println("observer2 has received!");
16
}
17
}
18
public interface Subject {
19
20
/*增加观察者*/
21
public void add(Observer observer);
22
23
/*删除观察者*/
24
public void del(Observer observer);
25
26
/*通知所有的观察者*/
27
public void notifyObservers();
28
29
/*自身的操作*/
30
public void operation();
31
}
32
public abstract class AbstractSubject implements Subject {
33
34
private Vector<Observer> vector = new Vector<Observer>();
35
36
public void add(Observer observer) {
37
vector.add(observer);
38
}
39
40
41
public void del(Observer observer) {
42
vector.remove(observer);
43
}
44
45
46
public void notifyObservers() {
47
Enumeration<Observer> enumo = vector.elements();
48
while(enumo.hasMoreElements()){
49
enumo.nextElement().update();
50
}
51
}
52
}
53
public class MySubject extends AbstractSubject {
54
55
public void operation() {
56
System.out.println("update self!");
57
notifyObservers();
58
}
59
}
60
public class ObserverTest {
61
62
public static void main(String[] args) {
63
Subject sub = new MySubject();
64
sub.add(new Observer1());
65
sub.add(new Observer2());
66
sub.operation();
67
}
68
}
迭代子模式
在迭代子模式中意识到了在两个接口之间就可一个接口调用另一个接口
说到迭代我们自然意识到类似于链表一样,有专门表示链表之间关联关系的描述一块和内部数据一块同样在迭代子模式中,一是需要遍历的对象,即聚集对象、二是迭代器对象,用于对聚集对象进行遍历访问。
Mycollection中定义了集合的一些操作,MyIterator中定义了一系列迭代操作,且持有Collection实例。
<wiz_code_mirror>
xxxxxxxxxx
95
1
public interface Collection {
2
3
public Iterator iterator();
4
5
/*取得集合元素*/
6
public Object get(int i);
7
8
/*取得集合大小*/
9
public int size();
10
}
11
12
public interface Iterator {
13
//前移
14
public Object previous();
15
16
//后移
17
public Object next();
18
public boolean hasNext();
19
20
//取得第一个元素
21
public Object first();
22
}
23
24
public class MyCollection implements Collection {
25
26
public String string[] = {"A","B","C","D","E"};
27
28
public Iterator iterator() {
29
return new MyIterator(this);
30
}
31
32
33
public Object get(int i) {
34
return string[i];
35
}
36
37
38
public int size() {
39
return string.length;
40
}
41
}
42
43
public class MyIterator implements Iterator {
44
45
private Collection collection;
46
private int pos = -1;
47
48
public MyIterator(Collection collection){
49
this.collection = collection;
50
}
51
52
53
public Object previous() {
54
if(pos > 0){
55
pos--;
56
}
57
return collection.get(pos);
58
}
59
60
61
public Object next() {
62
if(pos<collection.size()-1){
63
pos++;
64
}
65
return collection.get(pos);
66
}
67
68
69
public boolean hasNext() {
70
if(pos<collection.size()-1){
71
return true;
72
}else{
73
return false;
74
}
75
}
76
77
78
public Object first() {
79
pos = 0;
80
return collection.get(pos);
81
}
82
83
}
84
85
public class Test {
86
87
public static void main(String[] args) {
88
Collection collection = new MyCollection();
89
Iterator it = collection.iterator();
90
91
while(it.hasNext()){
92
System.out.println(it.next());
93
}
94
}
95
}
在实现的过程中和Java底层的集合类的操作过程类似,做了一些优化。
责任链模式
声明一个抽象类,在抽象类含有一个接口的引用,声明一个类继承抽象类实现那个接口,
对于责任链就是每一个对象都持有下一个对象的引用,形成一条链,请求在这条链上传递,直到某一对象决定处理该请求,但是发出者并不清楚到底最终那个对象处理该请求。责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。
Abstracthandler类提供了get和set方法,方便MyHandle类设置和修改引用对象,MyHandle类是核心,实例化后生成一系列相互持有的对象,构成一条链
<wiz_code_mirror>
xxxxxxxxxx
45
1
public interface Handler {
2
public void operator();
3
}
4
public abstract class AbstractHandler {
5
6
private Handler handler;
7
8
public Handler getHandler() {
9
return handler;
10
}
11
12
public void setHandler(Handler handler) {
13
this.handler = handler;
14
}
15
16
}
17
public class MyHandler extends AbstractHandler implements Handler {
18
19
private String name;
20
21
public MyHandler(String name) {
22
this.name = name;
23
}
24
25
26
public void operator() {
27
System.out.println(name+"deal!");
28
if(getHandler()!=null){
29
getHandler().operator();
30
}
31
}
32
}
33
public class Test {
34
35
public static void main(String[] args) {
36
MyHandler h1 = new MyHandler("h1");
37
MyHandler h2 = new MyHandler("h2");
38
MyHandler h3 = new MyHandler("h3");
39
40
h1.setHandler(h2);
41
h2.setHandler(h3);
42
43
h1.operator();
44
}
45
}
在链接的请求可以是一条链,可以是树,一个环,模式本事不约束这些,同时在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象。
命令模式
对于一个操作的执行,从将军下达命令,命令传输,士兵执行,这三部分进行了分离。
Invoke是调用者(司令员)、Receive是被调用者(士兵)、MyCommand是命令,实现Command接口,持有接受对象。
<wiz_code_mirror>
xxxxxxxxxx
42
1
public interface Command {
2
public void exe();
3
}
4
public class MyCommand implements Command {
5
6
private Receiver receiver;
7
8
public MyCommand(Receiver receiver) {
9
this.receiver = receiver;
10
}
11
12
13
public void exe() {
14
receiver.action();
15
}
16
}
17
public class Receiver {
18
public void action(){
19
System.out.println("command received!");
20
}
21
}
22
public class Invoker {
23
24
private Command command;
25
26
public Invoker(Command command) {
27
this.command = command;
28
}
29
30
public void action(){
31
command.exe();
32
}
33
}
34
public class Test {
35
36
public static void main(String[] args) {
37
Receiver receiver = new Receiver();
38
Command cmd = new MyCommand(receiver);
39
Invoker invoker = new Invoker(cmd);
40
invoker.action();
41
}
42
}
备忘录模式
主要目的就是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下,假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。
Original类是原始类,里面有需要保存的属性value及创建一个备忘录类,用来保存value值。Memento类是备忘录类,Storage类是存储备忘录的类,持有Memento类的实例
<wiz_code_mirror>
xxxxxxxxxx
76
1
public class Original {
2
3
private String value;
4
5
public String getValue() {
6
return value;
7
}
8
9
public void setValue(String value) {
10
this.value = value;
11
}
12
13
public Original(String value) {
14
this.value = value;
15
}
16
17
public Memento createMemento(){
18
return new Memento(value);
19
}
20
21
public void restoreMemento(Memento memento){
22
this.value = memento.getValue();
23
}
24
}
25
public class Memento {
26
27
private String value;
28
29
public Memento(String value) {
30
this.value = value;
31
}
32
33
public String getValue() {
34
return value;
35
}
36
37
public void setValue(String value) {
38
this.value = value;
39
}
40
}
41
public class Storage {
42
43
private Memento memento;
44
45
public Storage(Memento memento) {
46
this.memento = memento;
47
}
48
49
public Memento getMemento() {
50
return memento;
51
}
52
53
public void setMemento(Memento memento) {
54
this.memento = memento;
55
}
56
}
57
public class Test {
58
59
public static void main(String[] args) {
60
61
// 创建原始类
62
Original origi = new Original("egg");
63
64
// 创建备忘录
65
Storage storage = new Storage(origi.createMemento());
66
67
// 修改原始类的状态
68
System.out.println("初始化状态为:" + origi.getValue());
69
origi.setValue("niu");
70
System.out.println("修改后的状态为:" + origi.getValue());
71
72
// 回复原始类的状态
73
origi.restoreMemento(storage.getMemento());
74
System.out.println("恢复后的状态为:" + origi.getValue());
75
}
76
}
新建原始类时,value被初始化为egg,后经过修改,将value的值置为niu,最后倒数第二行进行恢复状态,结果成功恢复了。其实我觉得这个模式叫“备份-恢复”模式最形象。
状态模式
对于不同的状态,显示不同的状态,执行不同操作。
<wiz_code_mirror>
xxxxxxxxxx
60
1
public class State {
2
3
private String value;
4
5
public String getValue() {
6
return value;
7
}
8
9
public void setValue(String value) {
10
this.value = value;
11
}
12
13
public void method1(){
14
System.out.println("execute the first opt!");
15
}
16
17
public void method2(){
18
System.out.println("execute the second opt!");
19
}
20
}
21
public class Context {
22
23
private State state;
24
25
public Context(State state) {
26
this.state = state;
27
}
28
29
public State getState() {
30
return state;
31
}
32
33
public void setState(State state) {
34
this.state = state;
35
}
36
37
public void method() {
38
if (state.getValue().equals("state1")) {
39
state.method1();
40
} else if (state.getValue().equals("state2")) {
41
state.method2();
42
}
43
}
44
}
45
public class Test {
46
47
public static void main(String[] args) {
48
49
State state = new State();
50
Context context = new Context(state);
51
52
//设置第一种状态
53
state.setValue("state1");
54
context.method();
55
56
//设置第二种状态
57
state.setValue("state2");
58
context.method();
59
}
60
}
(今天还在想对于admin用户的操作什么的就是根据这个判断的)做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。
访问者模式
访问者模式就是一个类中一个方法调用另一个类中的方法,然后又回调调用本类中的另一个方法获取一些值。
来看看原码:一个Visitor类,存放要访问的对象,
- public interface Visitor {
- public void visit(Subject sub);
- }
- public class MyVisitor implements Visitor {
- @Override
- public void visit(Subject sub) {
- System.out.println("visit the subject:"+sub.getSubject());
- }
- }
- public interface Subject {
- public void accept(Visitor visitor);
- public String getSubject();
- }
- public class MySubject implements Subject {
- @Override
- public void accept(Visitor visitor) {
- visitor.visit(this);
- }
- @Override
- public String getSubject() {
- return "love";
- }
- }
- public class Test {
- public static void main(String[] args) {
- Visitor visitor = new MyVisitor();
- Subject sub = new MySubject();
- sub.accept(visitor);
- }
- }
该模式适用场景:如果我们想为一个现有的类增加新功能,不得不考虑几个事情:1、新功能会不会与现有功能出现兼容性问题?2、以后会不会再需要添加?3、如果类不允许修改代码怎么办?面对这些问题,最好的解决方法就是使用访问者模式,访问者模式适用于数据结构相对稳定的系统,把数据结构和算法解耦,
中介者模式
User类统一接口,User1和User2分别是不同的对象,二者之间有关联,如果不采用中介者模式,则需要二者相互持有引用,这样二者的耦合度很高,为了解耦,引入了Mediator类,提供统一接口,MyMediator为其实现类,里面持有User1和User2的实例,用来实现对User1和User2的控制。这样User1和User2两个对象相互独立,他们只需要保持好和Mediator之间的关系就行,剩下的全由MyMediator类来维护!
<wiz_code_mirror>
x
1
public interface Mediator {
2
public void createMediator();
3
public void workAll();
4
}
5
public class MyMediator implements Mediator {
6
7
private User user1;
8
private User user2;
9
10
public User getUser1() {
11
return user1;
12
}
13
14
public User getUser2() {
15
return user2;
16
}
17
18
19
public void createMediator() {
20
user1 = new User1(this);
21
user2 = new User2(this);
22
}
23
24
25
public void workAll() {
26
user1.work();
27
user2.work();
28
}
29
}
30
public abstract class User {
31
32
private Mediator mediator;
33
34
public Mediator getMediator(){
35
return mediator;
36
}
37
38
public User(Mediator mediator) {
39
this.mediator = mediator;
40
}
41
42
public abstract void work();
43
}
44
public class User1 extends User {
45
46
public User1(Mediator mediator){
47
super(mediator);
48
}
49
50
51
public void work() {
52
System.out.println("user1 exe!");
53
}
54
}
55
public class User2 extends User {
56
57
public User2(Mediator mediator){
58
super(mediator);
59
}
60
61
62
public void work() {
63
System.out.println("user2 exe!");
64
}
65
}
66
public class Test {
67
68
public static void main(String[] args) {
69
Mediator mediator = new MyMediator();
70
mediator.createMediator();
71
mediator.workAll();
72
}
73
}
解释器模式
Context类是一个上下文环境类,Plus和Minus分别是用来计算的实现,
<wiz_code_mirror>
xxxxxxxxxx
10
1
public interface Expression {
2
public int interpret(Context context);
3
}
4
public class Plus implements Expression {
5
6
7
public int interpret(Context context) {
8
return context.getNum1()+context.getNum2();
9
}
10
}
11
public class Minus implements Expression {
12
13
14
public int interpret(Context context) {
15
return context.getNum1()-context.getNum2();
16
}
17
}
18
public class Context {
19
20
private int num1;
21
private int num2;
22
23
public Context(int num1, int num2) {
24
this.num1 = num1;
25
this.num2 = num2;
26
}
27
28
public int getNum1() {
29
return num1;
30
}
31
public void setNum1(int num1) {
32
this.num1 = num1;
33
}
34
public int getNum2() {
35
return num2;
36
}
37
public void setNum2(int num2) {
38
this.num2 = num2;
39
}
40
41
42
}
43
44
public class Test {
45
46
public static void main(String[] args) {
47
48
// 计算9+2-8的值
49
int result = new Minus().interpret((new Context(new Plus()
50
.interpret(new Context(9, 2)), 8)));
51
System.out.println(result);
52
}
53
}
解释器模式用来做各种各样的解释器,如正则表达式等的解释器等等!