Java设计模式

简单工厂

简单工厂模式属于类的创建型模式,又叫静态工厂方法模式。
通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
1)工厂(Create)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。
工厂类可以被外界直接调用,创建所需的产品对象。
2)抽象(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
3)具体产品(Concrete Product)角色
简单工厂模式所创建的具体实例对象

简单工厂模式的优缺点

在这个模式中,工厂类是整个模式的关键所在。
它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。
用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。
有利于整个软件体系的结构的优化。
不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以”高内聚”方面做的并不好。
另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不好。

实例

Fruit接口

1
2
3
4
public interface Fruit{
//采集
public void get();
}

Apple实现Fruit接口

1
2
3
4
5
public class Apple implements Fruit{
public void get(){
System.out.print("采集苹果");
}
}

Banana实现Fruit接口

1
2
3
4
5
public class Banana implements Fruit{
public void get(){
System.out.print("采集香蕉");
}
}

简单工厂FruitFactory

1
2
3
4
5
6
7
public class FruitFactory{
public static Fruit getFruit(String type) throws InstantiationException,
IllegalAccessException, ClassNotFoundException{

Class fruit = Class.forName(type);
return (Fruit) fruit.newInstance();
}
}

测试类

1
2
3
4
5
6
7
8
9
public class MainClass{
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException{

Fruit apple = FruitFactory.getFruit("Apple");
Fruit banana = FruitFactory.getFruit("Banana");
apple.get();
banana.get();
}
}




工厂方法

工厂方法模式同样属于类的创建型模式又称多态工厂模式。
工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口。
这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
1.抽象工厂(Creator)角色
工厂方法模式的核心,任何工厂类都必须实现这个接口。
2.具体工厂(Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化产品对象。
3.抽象(Product)角色
工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
4.具体产品(Concrete Product)角色
工厂方法模式所创建的具体实例对象。

工厂方法模式和简单工厂模式比较

工厂方法的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则。
而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。

实例

Fruit接口

1
2
3
public interface Fruit{
public void get();
}

Apple类

1
2
3
4
5
public class Apple implements Fruit{
public void get(){
System.out.print("采集苹果");
}
}

Banana类

1
2
3
4
5
public class Banana implements Fruit{
public void get(){
System.out.print("采集香蕉");
}
}

Pear类

1
2
3
4
5
public class Pear implements Fruit{
public void get(){
System.out.print("采集梨子");
}
}

抽象的FruitFactory

1
2
3
public interface FruitFactory{
public Fruit getFruit();
}

AppleFactory

1
2
3
4
5
public class AppleFactory implements FruitFactory{
public Fruit getFruit(){
return new Apple();
}
}

BananaFactory

1
2
3
4
5
public class BananaFactory implements FruitFactory{
public Fruit getFruit(){
return new Banana();
}
}

PearFactory

1
2
3
4
5
public class PearFactory implements FruitFactory{
public Fruit getFruit(){
return new Pear();
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MainClass{
public static void main(String[] args){
FruitFactory ff = new AppleFactory();
Fruit apple = ff.getFruit();
apple.get();

FruitFactory ff2 = new BananaFactory();
Fruit banana = ff2.getFruit();
banana.get();

FruitFactory ff3 = new PearFactory();
Fruit pear = ff3.getFruit();
pear.get();
}
}

实例2

Operation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public abstract class Operation{
private double num1;
private double num2;

public double getNum1(){
return num1;
}

public void setNum1(double num1){
this.num1 = num1;
}

public double getNum2(double num2){
this.num2 = num2;
}

public abstract double getResult();
}

OperationFactory接口

1
2
3
public interface OperationFactory{
public Operation getOperation();
}

AddOperation

1
2
3
4
5
6
public class AddOperation extends Operation{
public double getResult(){
double result = this.getNum1() + this.getNum2();
return result;
}
}

AddOperationFactory

1
2
3
4
5
public class AddOperationFactory implements OperationFactory{
public Operation getOperation(){
return new AddOperation();
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MainClass{
public static void main(String[] args){
System.out.print("--计算器程序--");
System.out.print("输入第一个操作数");
Scanner scanner = new Scanner(System.in);
String strNum1 = scanner.nextLine();

System.out.println("输入运算符");
String strNum2 = scanner.nextLine();
double result = 0;
double num1 = Double.parseDouble(strNum1);
double num2 = Double.parseDouble(strNum2);

if("+".equals(oper)){
OperationFactory factory = new AddOperationFactory();
Operation operation = factory.getOperation();
operation.setNum1(num1);
operation.setNum2(num2);
result = operation.getResult();
}

System.out.print(strNum1 + oper + strNum2 + "=" + result);
}
}




抽象工厂

抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。
抽象工厂模式可以向客户端提供一接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。

角色及其职责

1.抽象工厂(Creator)角色
抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。
2.具体工厂(Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
3.抽象(Product)角色
抽象模式所创建的具体实例对象。
4.具体产品(Concrete Product)角色
抽象模式所创建的具体实例对象。
总结:抽象工厂中方法对应产品结构,具体工厂对应产品族。

实例

Fruit接口

1
2
3
public interface Fruit{
public void get();
}

Apple接口

1
2
3
public abstract class Apple implements Fruit{
public abstract void get();
}

Banana接口

1
2
3
public abstract class Banana implements Fruit{
public abstract void get();
}

FruitFactory接口

1
2
3
4
public interface FruitFactory{
public Fruit getApple();
public Fruit getBanana();
}

NorthApple类

1
2
3
4
5
public class NorthApple extends Apple{
public void get(){
System.out.print("采集北方苹果");
}
}

NorthBanana类

1
2
3
4
5
public class NorthBanana extends Banana{
public void get(){
System.out.print("采集北方香蕉");
}
}

NorthFruitFactory

1
2
3
4
5
6
7
8
9
public class NorthFruitFactory implements FruitFactory{
public Fruit getApple(){
return new NorthApple();
}

public Fruit getBanana(){
return new NorthBanana();
}
}

SouthApple

1
2
3
4
5
public class SouthApple extends Apple{
public void get(){
System.out.print("采集南方苹果");
}
}

SouthBanana

1
2
3
4
5
public class SouthBanana extends Banana{
public void get(){
System.out.print("采集南方香蕉");
}
}

SouthFruitFactory

1
2
3
4
5
6
7
8
9
public class SouthFruitFactory implements FruitFactory{
public Fruit getApple(){
return new SouthApple();
}

public Fruit getBanana(){
return new SouthBanan();
}
}

WenshiApple

1
2
3
4
5
public class WenshiApple extends Apple{
public void get(){
System.out.print("采集温室苹果");
}
}

WenshiBanana

1
2
3
4
5
public class WenshiBanana extends Banana{
public void get(){
System.out.print("采集温室香蕉");
}
}

WenshiFruitFactory

1
2
3
4
5
6
7
8
9
public class WenshiFruitFactory implements FruitFactory{
public Fruit getApple(){
return new WenshiApple();
}

public Fruit getBanana(){
return new WenshiBanana();
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MainClass{
public static void main(String[] args){
FruitFactory ff = new NorthFruitFactory();
Fruit apple = ff.getApple();
apple.get();

Fruit banana = ff.getBanana();
banana.get();

FruitFactory ff2 = new SouthFruitFactory();
Fruit apple2 = ff2.getApple();
apple2.get();

Fruit banana2 = ff2.getBanana();
banana2.get();

FruitFactory ff3 = new WenshiFruitFactory();
Fruit apple3 = ff3.getApple();
apple3.get();

Fruit banana3 = ff3.getBanana();
banana3.get();
}
}




单例模式

饿汉式
懒汉式
双重检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Person{
private String name;
private static Person person;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
private Person(){
}

public static Person getPerson(){
if(person == null){
synchronized (Person.class){
if(person == null){
person = new Person();
}
}
}
return person;
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
public class MainClass{
public static void main(String[] args){
Person per = Person.getPerson();
Person per2 = Person.getPerson();
per.setName("张三");
pre2.setName("李四");

System.out.print(per.getName());
System.out.print(per2.getNumber());
}
}




原型模式

Prototype模式是一种对象创建型模式,它采用复制原型对象的方法来创建对象的实例。
使用Prototype模式创建的实例,具有与原型一样的数据结构。

原型模式的特点

1.由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。
2.目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。
3.根据对象克隆的层次的不同,有浅克隆与深克隆。

原型模式应用场景。

在创建对象的时候,我们不只是希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据。
希望对目标对象的修改不影响既有的原型对象(深度克隆时完全互不影响)
隐藏克隆操作的细节,很多时候,对对象本身的克隆需要涉及到类本身的数据细节。

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class Person implements Cloneable{
private String name;
private int age;
private String sex;
private List<String> friends;
public List<String> getFriends(){
return friends;
}
public void setFriends(List<String> friends){
this.friends = friends;
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public int getAge(){
return age;
}

public void setAge(int age){
this.age = age;
}

public String getSex(){
return sex;
}

public void setSex(String sex){
this.sex = sex;
}

public Person clone(){
try{
Person person = (Person)super.clone();
List<String> newFriends = new ArrayList<String>();
for(String friend : this.getFriends()){
newfriends.add(friend);
}
person.setFriends(newfriends);
return person;
}catch(CloneNotSupportedException e){
e.printStackTrace();
return null;
}
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MainClass{
Person person1 = new Person();
List<String> friends = new ArrayList<String>();
friends.add("James");
friends.add("Yao");

person1.setFriends(friends);
Peron preson2 = person1.clone();
System.out.print(person1.getFriends());
System.out.print(person2.getFriends());

friends.add("Mike");
person1.setFriends(friends):
System.out.println(person1.getFriends());
System.out.println(person2.getFriends());

}




建造者模式

Builder模式是一种对象创建型模式。
用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方法,动态地创建具有复合属性的对象。

建造者模式应用场景

对象的创建:Builder模式是为对象的创建而设计的模式。
创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象
关注对象创建的各部分的创建过程:不同的工厂(这里指builder生成器)对产品属性有不同的创建方法。

实例

House类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class House{
private String floor;
private String wall;
private String housetop;
public String getFloor(){
return floor;
}
public void setFloor(String floor){
this.floor = floor;
}

public String getWall(){
return wall;
}

public void setWall(String wall){
this.wall = wall;
}

public String getHousetop(){
return housetop;
}

public void setHousetop(String housetop){
this.housetop = housetop;
}
}

HouseBuilder接口

1
2
3
4
5
6
public interface HouserBuilder{
public void makeFloor();
public void makeWall();
public void makeHousertop();
public House getHouse();
}

GongyuBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class GongyuBuilder implements HouseBuilder{
House house = new Houser();
public Houser getHouse(){
return house;
}

public void makeFloor(){
house.setFloor("公寓-->地板");
}

public void makeHousetop(){
house.setHousetop("公寓-->房顶");
}

public void makeWall(){
house.setWall("公寓-->墙");
}
}

PingFangBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class PingFangBuilder implements HouseBuilder{
House house = new House();
public void makeFloor(){
house.setFloor("平方-->地板");
}

public void makeHousetop(){
house.setHousetop("平方-->房顶");
}

public void makeWall(){
house.setWall("平方-->墙");
}

public House getHouse(){
return house;
}
}

HouseDirector

1
2
3
4
5
6
7
public class HouseDirector{
public void makeHouse(HouseBuilder builder){
builder.makeFloor();
builder.makeWall();
builder.makeHousetop();
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
public class MainClass{
public static void main(String[] args){
HouseBuilder builder = new GongyuBuilder();
HouseDirector director = new HouseDirector();
director.makeHouse(builder);

Houser house = builder.getHouse();
System.out.print(house.getFloor());
System.out.print(house.getWall());
System.out.print(house.getHousetop());
}
}




装饰者模式

装饰(Decorator)模式又称包装模式。
通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。

装饰模式的角色和职责

抽象组件角色:一个抽象接口,是被装饰类和装饰类的父接口。
具体组件角色:为抽象组件的实现类。
抽象装饰角色:包含一个组件的引用,并定义了与抽象组件一致的接口。
具体装饰角色:为抽象装饰角色的实现类。负责具体的装饰。

实例

Car

1
2
3
4
public interface Car{
public void show();
public void run();
}

CarDecorator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class CarDecorator implements Car{
private Car car;
public Car getCar(){
return car;
}
public void setCar(Car car){
this.car = car;
}

public CarDecorator(Car car){
this.car = car;
}

public abstract void show();
}

RunCar

1
2
3
4
5
6
7
8
9
public class RunCar implements Car{
public void run(){
System.out.print("可以跑");
}

public void show(){
this.run();
}
}

SwimCarDecorator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SwimCarDecorator extends CarDecorator{
public SwimCarDecorator(Car car){
super(car);
}

public void show(){
this.getCar().show();
this.swim();
}

public void swim(){
System.out.print("可以游");
}

public void run(){
}
}

FlyCarDecorator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class FlyCarDecorator extends CarDecorator{
public FlyCarDecorator(Car car){
super(car);
}

public void show(){
this.getCar().show();
this.fly();
}

public void fly(){
System.out.println("可以飞");
}

public void run(){

}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MainClass{
public static void main(String[] args){
Car car = new RunCar();
car.show();
System.out.println("----");

Car swimCar = new SwimCarDecorator(car);
swimCar.show();
System.out.println("----------");

Car flySwimCar = new FlyCarDecorator(swimCar);
flySwimCar.show();
}
}




策略模式

Strategy模式也叫策略模式是行为模式之一。
它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,
具体的算法选择交由客户端决定(策略)。
Stragey模式主要用来平滑地处理算法的切换。

策略模式的角色和职责

Strategy:策略(算法)抽象。
ConcreteStrategy:各种策略(算法)的具体实现。
Context:策略的外部封装类,或者受策略的容器类。根据不同策略执行不同的行为。策略由外部环境决定。

策略模式的优点

1.策略模式提供了管理相关的算法族的办法。
策略类的等级结构定义了一个算法或行为族。
恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。
2.策略模式提供了可以替换继承关系的办法。
继承可以处理多种算法或行为。
如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。
但是,这样一来算法或行为的使用者就和算法或行为混在一起。
决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。
继承使得动态改变算法或行为变得不可能。
3.使用策略模式可以避免使用多重条件转移语句。
多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑和算法或行为的逻辑混在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

策略模式的缺点

1.客户端必须知道所有的策略类,并自行决定使用哪一种策略。
这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。
换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
2.策略模式造成很多的策略类。
有时可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户单使用。
换言之,可以使用享元模式来减少对象的数量。

实例1

Strategy

1
2
3
public interface Strategy{
public void encrypt();
}

MDSStrategy

1
2
3
4
5
public class MDSStrategy implements Strategy{
public void encrypt(){
System.out.println("执行MDS加密");
}
}

MD5Strategy

1
2
3
4
5
public class MD5Strategy implements Strategy{
public void encrypt(){
System.out.println("执行MD5加密");
}
}

Context

1
2
3
4
5
6
7
8
9
10
public class Context{
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}

public void encrypt(){
this.strategy.encrypt();
}
}

测试类

1
2
3
4
5
6
public class MainClass{
public static void main(String[] args){
Context context = new Context(new MDSStrategy());
context.encrypt();
}
}

实例2

Strategy

1
2
3
public interface Strategy{
public double cost(double num);
}

StrategyA

1
2
3
4
5
public class StrategyA implements Strategy{
public double cost(double num){
return num * 0.8;
}
}

StrategyB

1
2
3
4
5
6
7
8
public class StrategyB implements Strategy{
public double cost(double num){
if(num >= 200){
return num - 50;
}
return num;
}
}

Context

1
2
3
4
5
6
7
8
9
10
11
public class Context{
private Strategy strategy;

public Context(Strategy strategy){
this.strategy = strategy;
}

public double cost(double num){
return this.strategy.cost(num);
}
}

测试类

1
2
3
4
5
6
7
8
public class MainClass{
public static void main(String[] args){
double num = 200;
Context context = new Context(new StrategyB());
double newNum = context.cost(num);
System.out.print("实际付账" + newNum + "圆");
}
}




观察者模式

Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象。
自动刷新对象状态。
Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

观察者模式的角色和职责

Subject(被观察者)
被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。
Subject需要维持(添加、删除、通知)一个观察者对象的队列列表。
ConcreteSubject 被观察者的具体实心。包含一些基本的属性状态及其他操作。
Observer(观察者)
接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得知通知。
ConcreteObserver
观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。

实例1

Person

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Person extends Observable{
private String name;
private String sex;
private int age;

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
this.setChanged();
this.notifyObservers();
}

public String getSex(){
return sex;
}

public void setSex(String sex){
this.sex =sex;
this.setChanged();
this.notifyObservers();
}

public int getAge(){
return age;
}

public void setAge(int age){
this.age = age;
this.setChanged();
this.notifyObservers();
}
}

MyObserver

1
2
3
4
5
public class MyObserver implements Observer{
public void update(Observable o , Object o){
System.out.print("对象发生了变化");
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
public class MainClass{
public static void main(String[] args){
Person person = new Person();
person.addObserver(new MyObserver());
person.addObserver(new MyObserver());
System.out.print(person.countObservers());
person.setName("xxx");
person.setAge("22");
person.setSex("男");
}
}

实例2

Article

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Article{
private String articleTitle;
private String articleContent;

public String getArticleTitle(){
return articleTitle;
}

public void setArticleTitle(String articleTitle){
this.articleTitle = articleTitle;
}

public String getArticleContent(){
return articleContent;
}

public void setArticleContent(String articleContent){
this.articleContent = articleContent;
}
}

BlogUser

1
2
3
4
5
6
7
8
9
10
11
public class BlogUser extends Observable{
public void publishBlog(String articleTitle,String articleContent){
Article art = new Article();
art.setArticleTitle(articleTitle);
art.setArticleContent(articleContent);
System.out.println("博主发表新文章文章标题:" + articleTitle + ",文章内容:" +
articleContent);
this.setChanged();
this.notifyObserver(art);
}
}

MyObserver

1
2
3
4
5
6
7
8
public class MyObserver implements Observer{
public void update(Observable o, Object arg){
Article art = (Article)arg;
System.out.print("博主发表新文章");
System.out.print("标题:"+ art.getArticleTitle());
System.out.print("内容:"+ art.getArticleContent());
}
}

测试类

1
2
3
4
5
6
7
public class MainClass{
public static void main(String[] args){
BlogUser user = new BlogUser();
user.addObserver(new MyObserver());
user.publishBlog("哈哈,博客上线了","人傻,钱多,速来");
}
}




享元模式

Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减少内存占用。

享元模式的角色和职责

抽象享元角色:所有具体享元类的父类,规定一些需要实现的公共接口。
具体享元角色:抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法。
享元工厂角色:负责创建和管理享元角色。

实例1

MyCharacter

1
2
3
4
5
6
7
8
9
public class MyCharacter{
private char mychar;
public MyCharacter(char mychar){
this.mychar = mychar;
}
public void display(){
System.out.println(mychar);
}
}

MyCharacterFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MyCharacterFactory{
private Map<Character,MyCharacter> pool;
public MyCharacterFactory(){
pool = new HashMap<Character, MyCharacter>();
}
public MyCharacter getMyCharacter(Character character){
MyCharacter myChar = pool.get(character);
if(myChar == null){
myChar = new MyCharacter(character);
pool.put(character, myChar);
}
return myChar;
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MainClass{
public static void main(String[] args){
MyCharacterFactory factory = new MyCharacterFactory();
MyCharacter myChar1 = factory.getMyCharacter('a');
MyCharacter myChar2 = factory.getMyCharacter('b');
MyCharacter myChar3 = factory.getMyCharacter('a');
MyCharacter myChar4 = factory.getMyCharacter('d');

myChar1.display();
myChar2.display();
myChar3.display();
myChar4.display();

if(myChar1 == myChar3){
System.out.println("true");
}else{
System.out.println("false");
}
}
}

实例2

Person

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Person{
private String name;
private int age;
private String sex;

public Person(String name, int age, String sex){
super();
this.name = name;
this.age = age;
this.sex = sex;
}

public Person(){
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public int getAge(){
return age;
}

public void setAge(int age){
this.age = age;
}

public String getSex(){
return sex;
}

public void setSex(String sex){
this.sex = sex;
}
}

Teacher

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Teacher extends Person{
private String number;
public String getNumber(){
return number;
}

public void setNumber(String number){
this.number = number;
}

public Teacher(String name,int age, String sex, String number){
super(name, age, sex);
this.number = number;
}

public Teacher(){
super();
}
}

TeacherFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TeacherFactory{
private Map<String, Teacher> pool;
public TeacherFactory(){
pool = new HashMap<String, Teacher>();
}
public Teacher getTeacher(String number){
Teacher teacher = pool.get(number);
if(teacher == null){
teacher = new Teacher();
teacher.setNumber(number);
pool.put(number,teacher);
}
return teacher;
}
}

测试类
MainClass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MainClass{
public static void main(String[] args){
TeacherFactory factory = new TeacherFactroy();
Teacher teacher1 = factory.getTeacher("0102034");
Teacher teacher2 = factory.getTeacher("0102035");
Teacher teacher3 = factory.getTeacher("0102034");
Teacher teahcer4 = factory.getTeacher("0102037");

System.out.println(teacher1.getNumber());
System.out.println(teacher2.getNumber());
System.out.println(teacher3.getNumber());
System.out.println(teacher4.getNumber());

if(teacher1 == teacher2){
System.out.println("true");
}else{
System.out.println("false");
}
}
}




代理模式

Proxy模式又叫做代理模式,是构造型的设计模式之一,
它可以为其它对象提供一种代理(Proxy)以控制对这个对象的访问。
所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,
而代理一般在交互的过程中(交互前后),进行某些特别的处理。

代理模式的角色和职责

subject(抽象主题角色) 真实主题与代理主题的共同接口。
RealSubject(真实主题角色):定义了代理角色所代表的真实对象。
Proxy(代理主题角色):含有对真实主题角色的引用,代理角色通常在将客户端调用传递给真实主题对象之前或之后执行某些操作,而不是单纯返回真实的对象。

动态代理

1.InvocationHandler接口
2.invoke方法
3.Proxy.newProxyInstance();

实例1

Subject

1
2
3
public interface Subject{
public void sellBook();
}

RealSubject

1
2
3
4
5
public class RealSubject implements Subject{
public void sellBook(){
System.out.println("卖书");
}
}

ProxySubject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ProxySubject implements Subject{
private RealSubject realSubject;

public void sellBook(){
dazhe(); //before
if(realSubject == null){
realSubject = new RealSubject();
}
realSubject.sellBook();
give(); //after
}

public void dazhe(){
System.out.println("打折");
}

public void give(){
System.out.println("赠送代金券");
}
}

测试类

1
2
3
4
5
6
public class MainClass{
public static void main(String[] args){
ProxySubject proxySubject = new ProxySubject();
proxySubject.sellBook();
}
}

实例2

Subject

1
2
3
public interface Subject{
public void sellBook();
}

RealSubject

1
2
3
4
5
public class RealSubject implements Subject{
public void sellBook(){
System.out.println("卖书");
}
}

MyHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class MyHandler implements InvocationHandler{
private RealSubject realSubject;
public void setRealSubject(RealSubject realSubject){
this.realSubject = realSubject;
}
public Object invoke(Object proxy,Method method,Object[] args){
Object result = null;
dazhe();
try{
result = method.invoke(realSubject, args);
}catch(IllegalArgumentException e){
e.printStackTrace();
}catch(IllegalAccessException e){
e.printStackTrace();
}catch(InvocationTargetException e){
e.printStackTrace();
}
give();
return result;
}

public void dazhe(){
System.out.println("打折");
}

public void give(){
System.out.println("赠送代金券");
}

}

测试类

1
2
3
4
5
6
7
8
9
10
11
public class MainClass{
public static void main(String[] args){
RealSubject realSubject = new RealSubject();
MyHandler myHandler = new MyHandler();
myHandler.setRealSubject(realSubject);

Subject proxySubject = (Subject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
realSubject.getClass().getInterfaces(), myHandler);
proxySubject.sellBook();
}
}




外观模式

Facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种。
Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。
这个一致的简单的界面被称作facade。

外观模式的角色和职责

Facade 为调用方定义简单的调用接口。
Clients 调用者。通过Facade接口调用提供某功能的内部类群。
Packages 功能提供者。指提供功能的类群(模块或子系统)。

实例1

SystemA

1
2
3
4
5
6
public class SystemA{
//A为子系统实现功能
public void dSomething(){
System.out.println("实现A子系统功能");
}
}

SystemB

1
2
3
4
5
6
public class SystemB{
//B子系统实现功能
public void doSomething(){
System.out.println("实现B子系统功能");
}
}

SystemC

1
2
3
4
5
6
public class SystemC{
//C子系统实现功能
public void doSomething(){
System.out.println("实现C子系统功能");
}
}

Facade

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Facade{
private SystemA systemA;
private SystemB systemB;
private SystemC systemC;

public Facade(){
systemA = new SystemA();
systemB = new SystemB();
systemC = new SystemC();
}

public void doABC(){
this.systemA.doSomething();
this.systemB.doSomething();
this.systemC.doSomething();
}

public void doAB(){
this.systemA.doSomething();
this.systemB.doSomething();
}
}

测试类1

1
2
3
4
5
6
public class MainClass1{
public static void main(String[] args){
Facade facade = new Facade();
facade.doABC();
}
}

测试类2

1
2
3
4
5
6
public class MainClass2{
public static void main(String[] args){
Facade facade = new Facade();
facade.doAB();
}
}

实例2

GuoZai

1
2
3
4
5
public class GuoZai{
public void mai(){
System.out.println("买国债");
}
}

Gupiao

1
2
3
4
5
public class Gupiao{
public void mai(){
System.out.println("买股票");
}
}

Qihuo

1
2
3
4
5
public class Qihuo{
public void chao(){
System.out.println("买期货");
}
}

JiJin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class JiJin{
private Gupiao gupiao;
private GuoZai guozai;
private Qihuo qihuo;

public JiJin(){
this.guozai = new GuoZai();
this.gupiao = new Gupiao();
this.qihuo = new Qihuo();
}

public void maiJijinA(){
this.guozai.mai();
this.gupiao.mai();
}

public void maiJijinB(){
this.guozai.mai();
this.gupiao.mai();
this.qihuo.chao();
}
}

测试类

1
2
3
4
5
6
public class MainClass{
public static void main(String[] args){
JiJin jijin = new JiJin();
jijin.maiJijinB();
}
}




组合模式

Composite模式也叫组合模式,是构造型的设计模式之一。
通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整颗树。

组合模式的角色和职责

Component(树形结构的节点抽象)
为所有的对象定义统一的接口(公共属性,行为等的定义)
提供管理子节点对象的接口方法
[可选]提供管理父节点对象的接口方法

Leaf(树形结构的叶节点)
Component的实现子类

Composite(树形结构的枝节点)
Component的实现子类、

实例

IFile

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface IFile{
//显示文件或文件夹的名称
public void display();

//添加
public boolean add(IFile file);

//移除
public boolean remove(IFile file);

//获得子节点
public List<IFile> getChild();
}

File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class File implements IFile{
private String name;
public File(String name){
this.name = name;
}

public void display(){
System.out.println(name);
}

public List<IFile> getChild(){
return null;
}

public boolean add(IFile file){
return false;
}

public boolean remove(IFile file){
return false;
}
}

Folder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Folder implements IFile{
private String name;
private List<IFile> children;

public Folder(String name){
this.name = name;
children = new ArrayList<IFile>();
}

public void display(){
System.out.println(name);
}

public List<IFile> getChild(){
return children;
}

public boolean add(IFile file){
return children.add(file);
}

public boolean remove(IFile file){
return children.remove(file);
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class MainClass{
public static void main(String[] args){
//C盘
Folder rootFolder = new Folder("C:");
//newFolder目录
Folder newFolder = new Folder("newFolder");
//newfile.txt文件
File newfile = new File("newfile.txt");

rootFolder.add(newFolder);
rootFolder.add(newfile);

//inewfolder目录
Folder inewFolder = new Folder("inewfolder");
File inewfile = new File("inewfile.txt");
newFolder.add(inewFolder);
newFolder.add(inewfile);

Folder iinewFolder = new Folder("iinewfolder");
File iinewfile = new File("iinewfile.txt");
inewFolder.add(iinewFolder);
inewFolder.add(iinewfile);

displayTree(rootFolder, 0);
}

public static void displayTree(IFile rootFolder, int deep){
for(int i = 0 ; i < deep; i++){
System.out.print("--");
}
//显示自身的名称
rootFolder.display();
//获得子树
List<IFile> children = rootFolder.getChild();
//遍历子树
for(IFile file : children){
if(file instanceof File){
for(int i = 0 ; i <= deep; i++){
System.out.print("--");
}
file.display();
}else{
displayTree(file, deep + 1);
}
}
}
}




解释器模式

Interpreter模式也叫解释器模式,是行为模式之一。
它是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法。
简单地说,Interpreter模式是一种简单的语法解释器架构。

解释器模式应用场景

当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:

  • 该文法简单对于复杂的文法,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。
  • 效率不是一个关键问题,最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下,转换器仍可用解释器模式实现,该模式仍是有用的。

    解释器模式的角色和职责

    Context 解释器上下文环境类。用来存储解释器的上下文环境,比如需要解释的文法等。
    AbstractExpression 解释器抽象类。
    ConcreteExpression 解释器具体实现类。

    实例

    Expression类
    1
    2
    3
    4
    5
    6
    /*
    *抽象解释器
    */

    public abstract class Expression{
    public abstract void interpret(Context context);
    }

MinusExpression类

1
2
3
4
5
6
7
8
9
10
public class MinusExpression extends Expression{
public void interpret(Context context){
System.out.println("自动递减");
String input = context.getInput();
int inInput = Integer.parseInt(input);
--inInput;
context.setInput(String.valueOf(inInput));
context.setOutput(inInput);
}
}

PlusExpression类

1
2
3
4
5
6
7
8
9
10
public class PlusExpression extends Expression{
public void interpret(Context context){
System.out.println("自动递减");
String input = context.getInput();
int intInput = Integer.parseInt(input);
++intInput;
context.setInput(String.valueOf(intInput));
context.setOutput(intInput);
}
}

Context类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Context{
private String input;
private int output;

public Context(String input){
this.input = input;
}

public String getInput(){
return input;
}

public void setInput(String input){
this.input = input;
}

public int getOutput(){
return output;
}

public void setOutput(int output){
this.output = output;
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MainClass{
public static void main(String[] args) {
String number = "20";
Context context = new Context(number);

List<Expression> list = new ArrayList<Expression>();
list.add(new PlusExpression());
list.add(new PlusExpression());
list.add(new MinusExpression());
list.add(new MinusExpression());
list.add(new MinusExpression());
list.add(new MinusExpression());

for(Expression ex :list){
ex.interpret(context);
System.out.println(context.getOutput());
}
}
}




中介者模式

Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种。
Mediator模式是行为模式之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用。

中介者模式的角色和职责

mediator 中介者类的抽象父类
concreteMediator 具体的中介者类。
colleague 关联类的抽象父类。
concreteColleague 具体的关联类。

中介者模式的优点

  • 将系统按功能分割成更小的对象,符合类的最小设计原则
  • 对关联对象的集中控制
  • 减小类的耦合程度,明确类之间的相互关系:当类之间的关系过于复杂时,其中任何一个类的修改都会影响到其他类,不符合类的设计的开闭原则,而Mediator模式将原来相互依存的多对多的类之间的关系简化为Mediator控制类与其他关联类的一对多的关系,当其中一个修改时,可以对其他关联类不产生影响(即使有修改,也集中在Mediator控制类)。
  • 有利于提高类的重用性

    实例

    Person
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    public abstract class Person{
    private String name;
    private int condition;
    private Mediator mediator;

    public Person(String name,int condition, Mediator mediator){
    super();
    this.name = name;
    this.condition = condition;
    this.mediator = mediator;
    }

    public Mediator getMediator(){
    return mediator;
    }

    public void setMediator(Mediator mediator){
    this.mediator = mediator;
    }

    public String getName(){
    return name;
    }

    public void setName(String name){
    this.name = name;
    }

    public int getCondition(){
    return condition;
    }

    public void setCondition(int condition){
    this.condition = condition;
    }

    public abstract void getPartner(Person person);

    }

Mediator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Mediator{
private Man man;
private Woman woman;

public void setMan(Man man){
this.man = man;
}

public void setWoman(Woman woman){
this.woman = woman;
}

public void getPartner(Person person){
if(person instanceof Man){
this.setMan((Man)person);
}else{
this.setWoman((Woman)person);
}

if(man == null || woman == null){
System.out.println("汗,不是同性恋");
}else{
if(man.getCondition() == woman.getCondition()){
System.out.println(man.getName() + "和" + woman.getName() + "绝配");
}else{
System.out.println(man.getName() + "和" + woman.getName() + "不相配");
}
}
}
}

Man

1
2
3
4
5
6
7
8
9
10
public class Man extends Person{
public Man(String name, int condition, Mediator mediator){
super(name, condition, mediator);
}

public void getPartner(Person person){
this.getMediator().setMan(this);
this.getMediator().getPartner(person);
}
}

Woman

1
2
3
4
5
6
7
8
9
10
public class Woman extends Person{
public Woman(String name, int condition, Mediator mediator){
super(name, condition, mediator);
}

public void getPartner(Person person){
this.getMediator().setWoman(this);
this.getMediator().getPartner(person);
}
}

测试类

1
2
3
4
5
6
7
8
9
10
public class MainClass{
public static void main(String[] args){
Mediator mediator = new Mediator();
Person zhangsan = new Man("张三", 7, mediator);
Person lisi = new Man("李四", 7, mediator);
Person xiaofang = new Woman("小芳", 7, mediator);
zhangsan.getPartner(lisi);
xiaofang.getPartner(lisi);
}
}




职责链模式

Chain of Responsibility(CoR)模式页脚职责链式或者职责连锁模式,是行为模式之一,
该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作职责链模式。

职责链模式的应用场景

例1:比如客户Client要完成一个任务,这个任务包括a,b,c,d四个部分。
首先客户Client把任务交给A,A完成a部分之后,把任务交给B,B完成b部分,…,直到D完成d部分。
例2:比如政府部分的某项工作,县政府先完成自己能处理的部分,不能处理的部分交给省政府,省政府再完成自己的职责范围内的部分,
不能处理的部分交给中央政府,中央政府最后完成该项工作。
例3:软件窗口的消息传播。
例4:SERVLET容器的过滤其(Filter)框架实现。

职责链模式的基本条件

要实现Chain of Responsibility模式,需要满足该模式的基本条件:
1.对象链的组织。需要将某任务的所有职责执行对象以链的形式加以组织。
2.消息或请求的传递。将消息或请求沿着对象链传递,以让处于对象链中的对象得到处理机会。
3.处于对象链中的对象的职责分配。不同的对象完成不同的职责。
4.任务的完成。处于对象链的末尾的对象结束任务并停止消息或请求的继续传递。

职责链模式的角色和职责

Handler 处理类的抽象父类。
concreteHandler 具体的处理类。

职责链模式的优缺点

优点:
1.责任的分担。每个类只需要处理自己该处理的工作(不该处理的传递给下一个对象完成),明确各类的责任范围,符合类的最小封装原则。
2.可以根据需要自由组合工作流程。如工作流程发生变化,可以通过重新分配对象链便可适应新的工作流程。
3.类与类之间可以以松耦合的形式加以组织。
缺点:
因为处理时以链的形式在对象间传递消息,根据实现方式不同,有可能会影响处理的速度。

实例

1
2
3
4
5
6
7
8
9
public abstract class CarHandler{
protected CarHandler carHandler;
public CarHandler setNextHandler(CarHandler carHandler){
this.carHandler = carHandler;
return this.carHandler;
}

public abstract void HandlerCar();
}

CarHeadHandler

1
2
3
4
5
6
7
8
public class CarHeadHandler extends CarHandler{
public void HandlerCar(){
System.out.println("组装车头");
if(this.carHandler != null){
this.carHandler.HandlerCar();
}
}
}

CarBodyHandler

1
2
3
4
5
6
7
8
public class CarBodyHandler extends CarHandler{
public void HandlerCar(){
System.out.println("组装车身");
if(this.carHandler != null){
this.carHandler.HandlerCar();
}
}
}

CarTailHandler

1
2
3
4
5
6
7
8
public class CarTailHandler extends CarHandler{
public void HandlerCar(){
System.out.println("组装车尾");
if(this.carHandler != null){
this.carHandler.HandlerCar();
}
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MainClass{
public static void main(String[] args){
CarHandler headH = new CarHeadHandler();
CarHandler bodyH = new CarBodyHandler();
CarHandler tailH = new CarTailHandler();

//组装顺序 车头-->车身-->车尾
headH.setNextHandler(bodyH);
bodyH.setNextHandler(tailH);
headH.HandlerCar();

System.out.println("-----");

//顺序改变, 车身-->车头-->车尾
bodyH.setNextHandler(headH);
headH.setNextHandler(tailH);
bodyH.HandlerCar();

//简便操作
bodyH.setNextHandler(headH).setNextHandler(tailH);
bodyH.HandlerCar();

}
}




迭代模式

Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委托给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。

不使用迭代模式的应用

在应用Iterator之前,首先应该明白Iterator模式用来解决什么问题。
或者说,如果不使用Iterator模式,会存在什么问题。
1.由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法。
2.让调用者自己实现遍历。直接暴露数据细节给外部。

迭代模式的角色和职责

Iterator(迭代器接口):
该接口必须定义实现迭代功能的最小定义方法集,比如提供hasNext()和next()方法。
ConcreteIterator(迭代器实现类):
迭代器接口Iterator的实现类。可以根据具体情况加以实现。
Aggregate(容器接口):
定义基本功能以及提供类似Iterator iterator()的方法。
concreteAggregate(容器实现类):
容器接口的实现类。必须实现Iterator iterator()方法。

迭代模式的优点

1.实现功能分离,简化容器接口。让容器只实现本身的基本功能,把迭代功能委让给外部类实现,符合类的设计原则。
2.隐藏容器的实现细节。
3.为容器或其子容器提供了一个统一接口,一方面方便调用;另一方面使得调用者不必关注迭代器的实现细节。
4.可以为容器或其子容器实现不同的迭代方法或多个迭代方法。

实例

Book

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Book{
private String ISBN;
private String name;
private double price;

public Book(String isbn,String name,double price){
ISBN = isbn;
this.name = name;
this.price = price;
}

public String getISBN(){
return ISBN;
}

public String getName(){
return name;
}

public void setName(){
this.name = name;
}

public double getPrice(){
return price;
}

public void setPrice(double price){
this.price = price;
}

public void display(){
System.out.println("ISBN=" + ISBN = ",name = " + name + ",price" + price);
}
}

BookList

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class BookList{
private List<Book> bookList;
private int index;
private Iterator iterator;

public BookList(){
bookList = new ArrayList<Book>();
}

public void addBook(Book book){
bookList.add(book);
}

public void deleteBook(Book book){
int bookIndex = bookList.indexOf(book);
bookList.remove(bookIndex);
}

public Iterator Iterator(){
return new Itr();
}

private class Itr implements Iterator{
public boolean hasNext(){
if(index >= bookList.size()){
return false;
}
return true;
}

public Object next(){
return bookList.get(index++);
}

public void remove(){
}
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MainClass{
public static void main(String[] args){
BookList bookList = new BookList();

Book book1 = new Book("010203", "Java编程思想", 90);
Book book2 = new Book("010204", "Java从入门到精通", 60);

bookList.addBook(book1);
bookList.addBook(book2);

Iterator iter = bookList.Iterator();
while(iter.hasNext()){
Book book = (Book)iter.next();
book.display();
}
}
}




模板方法模式

Template Method模式也叫模版方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委托给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为。

模版方法的应用场景

Template Method模式一般应用在具有以下条件的应用中:

  • 具有统一的操作步骤或操作过程
  • 具有不同的操作细节
  • 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同

    模版方法模式的角色和职责

    AbstractClass:抽象类的父类
    ConcreteClass:具体的实现子类
    templateMethod():模版方法
    method1()与method2():具体步骤方法

    实例

    MakeCar
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public abstract class MakeCar{
    public abstract void makeHead();

    public abstract void makeBody();

    public abstract void makeTail();

    public void make(){
    this.makeHead();
    this.makeBody();
    this.makeTail();
    }
    }

MakeJeep

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MakeJeep extends MakeCar{
public void makeBody(){
System.out.println("jeep:组装车身");
}

public void makeHead(){
System.out.println("jeep:组装车头");
}

public void makeTail(){
System.out.println("jeep:组装车尾");
}
}

MakeKa

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MakeKa extends MakeCar{
public void makeBody(){
System.out.println("ka:组装车身");
}

public void makeHead(){
System.out.println("ka:组装车头");
}

public void makeTail(){
System.out.println("ka:组装车尾");
}
}

MakeBus

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MakeBus extends MakeCar{
public void makeBody(){
System.out.println("bus:组装车身");
}

public void makeHead(){
System.out.println("bus:组装车头");
}

public void makeTail(){
System.out.println("bus:组装车尾");
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MainClass{
public static void main(String[] args){
MakeCar bus = new MakeBus();
bus.make();

System.out.println("--------------------");
MakeCar jeep = new MakeJeep();
jeep.make();

System.out.println("--------------------");
MakeCar ka = new MakeKa();
ka.make();
}
}




备忘录模式

Memento模式也叫备忘录模式,是行为模式之一,它的作用是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。

备忘录模式的角色和职责

Originator(原生者)
需要被保存状态以便恢复的那个对象。
Memento(备忘录)
该对象由Originator创建,主要用来保存Originator的内部状态。
Caretaker(管理者)
负责在适当的时间保存/恢复Originator对象的状态。

实例

Memento

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Memento{
private String name;
private String sex;
private int age;

public Memento(String name,String sex,int age){
this.name = name;
this.sex = sex;
this.age = age;
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public String getSex(){
return sex;
}

public void setSex(String sex){
this.sex = sex;
}

public int getAge(){
return age;
}

public void setAge(int age){
this.age = age;
}
}

Person

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class Person{
private String name;
private String sex;
private int age;

public Person(){
}

public Person(String name,String sex,int age){
this.name = name;
this.sex = sex;
this.age = age;
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public String getSex(){
return sex;
}

public void setSex(String sex){
this.sex = sex;
}

public int getAge(){
return age;
}

public void setAge(int age){
this.age = age;
}

public void display(){
System.out.println("name:" + name + ",sex:" + sex + ",age:" + age);
}

//创建一个备份
public Memento createMemento(){
return new Memento(name, sex, age);
}

public void setMemento(Memento memento){
this.name = memento.getName();
this.sex = memento.getSex();
this.age = memento.getAge();
}
}

Caretaker

1
2
3
4
5
6
7
8
9
10
public class Caretaker{
private Memento memento;
public Mement getMemento(){
return memento;
}

public void setMemento(Memento memento){
this.memento = memento;
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MainClass{
public static void main(String[] args){
Person per = new Person("xxx", "man", 22);
Caretaker caretaker = new Caretaker();
caretaker.setMemento(per.createMemento());

per.display();

per.setName("xxls");
per.setSex("woman");
per.setAge(11);

per.display();

per.setMemento(caretaker.getMemento());
per.display();
}
}




状态模式

State模式也叫状态模式,是行为设计模式的一种。
State模式允许通过改变对象的内部状态而改变对象的行为,这个行为表现得就好像改了它的类一样。

状态模式的应用场景

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。
把状态的判断转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。

状态模式的角色和职责

Context:用户对象
拥有一个State类型的成员,以标识对象的当前状态。
State:接口或基类
封装与Context的特定状态相关的行为
ConcreteState:接口实现类或子类
实现了一个与Context某个状态相关的行为。

实例

State

1
2
3
public abstract class State{
public abstract void doSomething(Person person);
}

MState

1
2
3
4
5
6
7
8
9
10
public class MState extends State{
public void doSomething(Person person){
if(person.getHour() == 7){
System.out.println("吃早餐");
}else{
person.setState(new LState());
person.doSomething();
}
}
}

LState

1
2
3
4
5
6
7
8
9
10
public class LState extends State{
public void doSomething(Person person){
if(person.getHour() == 12){
System.out.println("吃午餐");
}else{
person.setState(new SState());
person.doSomething();
}
}
}

SState

1
2
3
4
5
6
7
8
9
10
public class SState extends State{
public void doSomething(Person person){
if(person.getHour() == 18){
System.out.println("吃晚饭");
}else{
person.setState(new NoState());
person.doSomething();
}
}
}

NoState

1
2
3
4
5
public class NoState extends State{
public void doSomething(Person person){
System.out.println(person.getHour() + "未定义");
}
}

Person

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Person{
private int hour;
private State state;

public int getHour(){
return hour;
}

public void setHour(int hour){
this.hour = hour;
}

public Person(){
state = new MState();
}

public void doSomething(){
state.doSomething(this);
//复位
state = new MState();
}

public State getState(){
return state;
}

public void setState(State state){
this.state = state;
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MainClass{
public static void main(String[] args){
Person person = new Person();

person.setHour(7);
person.doSomething();

person.setHour(12);
person.doSomething();

person.setHour(18);
person.doSomething();

person.setHour(7);
person.doSomething();

person.setHour(18);
person.doSomething();
}
}




命令模式

Command模式也叫命令模式,是行为设计模式的一种。
Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。

命令模式的应用场景

在面向对象的设计,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;
设置调用参数;调用目标对象的方法。
但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。
整个调用过程比较频繁,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。
调用前后需要对调用参数进行某些处理。
调用前后需要进行额外处理,比如日志、缓存、记录历史操作等。

命令模式的角色和职责

Command Command抽象类
ConcreteCommand Command的具体实现类
Receiver 需要被调用的目标对象
Invorker 通过Invorker执行Command对象

实例

Peddler

1
2
3
4
5
6
7
8
9
public class Peddler{
public void sellApple(){
System.out.println("卖苹果");
}

public void sellBanana(){
System.out.println("卖香蕉");
}
}

Command

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public abstract class Command{
private Peddler peddler;
public Command(Peddler peddler){
this.peddler = peddler;
}

public Peddler getPeddler(){
return peddler;
}

public void setPeddler(Peddler peddler){
this.peddler = peddler;
}

public abstract void sell();
}

Waiter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Waiter{
private List<Command> commands = new ArrayList<Command>();

public void setOrder(Command command){
commands.add(command);
}

public void removeOrder(Command command){
commands.remove(command);
}

public void sell(){
for(Command command : commands){
command.sell();
}
}
}

AppleCommand

1
2
3
4
5
6
7
8
9
public class AppleCommand extends Command{
public AppleCommand(Peddler peddler){
super(peddler);
}

public void sell(){
this.getPeddler().sellApple();
}
}

BananaCommand

1
2
3
4
5
6
7
8
9
public class BananaCommand extends Command{
public BananaCommand(Peddler peddler){
super(peddler);
}

public void sell(){
this.getPeddler().sellBanana();
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MainClass{
public static void main(String[] args){
Peddler peddler = new Peddler();

Command appleCommand = new AppleCommand(peddler);
Command bananaCommand = new BananaCommand(peddler);

Waiter waiter = new Waiter();

waiter.setOrder(appleCommand);
waiter.setOrder(bananaCommand);

waiter.removeOrder(appleCommand);
waiter.sell();
}
}




访问者模式

Visitor模式也叫访问者模式,是行为模式之一,它分离对象的数据和行为。
使用Visitor模式,可以不修改已有类的情况下,增加新的操作。

访问者模式的应用示例

比如有一个公园,有一到多个不同的组成部分;
该公园存在多个访问者:

  • 清洁工A负责打扫公园A部分
  • 清洁工B负责打扫公园B部分
  • 公园管理者负责检点各项事务是否完成
  • 上级领导可以视察公园
    也就是说,对于同一个公园,不同的访问者有不同的行为操作,而且访问者的种类也可能需要根据时间的推移而变化(行为的扩展性)。

    访问者模式的角色和职责

    1.访问这角色(visitor)
    为该对象结构中on个具体元素角色声明一个访问操作接口。
    该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。
    这样访问者就可以通过该元素角色的特定接口直接访问它。
    2.具体访问者角色(concrete visitor):
    实现每个由访问者角色(visitor)声明的操作
    3.元素角色(Element)
    定义一个Accept操作,它以一个访问者为参数
    4.具体元素角色(Concrete Element)
    实现由元素角色提供的Accept操作
    5.对象结构角色(Object Structure)
    这是使用访问者模式必备的角色。
    它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;
    可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序结合。

    实例

    ParkElement
    1
    2
    3
    public interface ParkElement{
    public void accept(Visitor visitor);
    }

Visitor

1
2
3
4
5
public interface Visitor{
public void visit(Park park);
public void visit(ParkA parkA);
public void visit(ParkB parkB);
}

Park

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Park implements ParkElement{
private String name;
private ParkA parkA;
private ParkB parkB;

public Park(){
this.parkA = new ParkA();
this.parkB = new ParkB();
parkA.setName("A");
parkB.setName("B");
}

public void accept(Visitor visitor){
visitor.visit(this);
parkA.accept(visitor);
parkB.accept(visitor);
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}
}

ParkA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ParkA implements ParkElement{
private String name;
public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public void accept(Visitor visitor){
visitor.visit(this);
}
}

ParkB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ParkB implements ParkElement{
private String name;
public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public void accept(Visitor visitor){
visitor.visit(this);
}
}

VisitorA

1
2
3
4
5
6
7
8
9
10
11
12
public class VisitorA implements Visitor{
public void visit(Park park){

}

public void visit(ParkA parkA){
System.out.println("清洁工A:完成公园" + parkA.getName() +"的卫生");
}

public void visit(ParkB parkB){
}
}

VisitorB

1
2
3
4
5
6
7
8
9
10
11
12
public class VisitorB implements Visitor{
public void visit(Park park){
}

public void visit(ParkA parkA){

}

public void visit(ParkB parkB){
System.out.println("清洁工B:完成公园" + parkB.getName() + "的卫生");
}
}

VisitorManager

1
2
3
4
5
6
7
8
9
10
11
public class VisitorManager implements Visitor{
public void visit(Park park){
System.out.println("管理员:负责" + park.getName() + "卫生检查");
}
public void visit(ParkA parkA){
System.out.println("管理员:负责公园" + parkA.getName() + "部分卫生检测");
}
public void visit(ParkB parkB){
System.out.println("管理员:负责公园" + parkB.getName() + "部分卫生检查");
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MainClass{
public static void main(String[] args){
Park park = new Park();
park.setName("大商所公园");
VisitorA visitorA = new VisitorA();
park.accept(visitorA);

VisitorB visitorB = new VisitorB();
park.accept(visitorB);

VisitorManager visitorManager = new VisitorManager();
park.accept(visitorManager);
}
}