- 0 概述
- 1 单例模式
- 2 工厂模式
- 3 建造者模式
- 4 原型模式
- 5 适配器模式
- 6 静态代理模式
- 7 动态代理模式
- 8 桥接模式
- 9 组合模式
- 10 装饰器模式
- 11 外观(门面)模式
- 12 享元模式
- 13 责任链模式
- 14 迭代器(游标 cursor)模式
0 概述
创建型模式:
单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。
结构型模式:
适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:
模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式
1 单例模式
五种实现方式
1.饿汉式
/**
* 单例模式-饿汉式
* 类初始化时,立即加载这个对象,线程安全
*/
public class EagerSingleton {
private static EagerSingleton instance = new EagerSingleton();
/**
* 私有化构造器
*/
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
2.懒汉式
/**
* 单例模式-懒汉式
* 使用时再创建实例,为保证线程安全需要方法同步,效率低
*/
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static synchronized LazySingleton getInstance() {
if(instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
3.双重检查锁
/**
* 单例模式-双重检查锁
* 由于编译器优化原因和JVM底层内部模型原因,偶尔会出问题,不建议使用
*/
public class DoubleCheckSingleton {
private static DoubleCheckSingleton instance;
public static DoubleCheckSingleton getInstance() {
if(instance == null) {
DoubleCheckSingleton dc;
synchronized (DoubleCheckSingleton.class) {
dc = instance;
if(dc == null) {
synchronized (DoubleCheckSingleton.class) {
if(dc == null) {
dc = new DoubleCheckSingleton();
}
}
instance = dc;
}
}
}
return instance;
}
}
4.静态内部类
/**
* 单例模式-静态内部类
* 线程安全\延时加载且调用效率高
*/
public class StaticInnerSingleton {
private static class StaticInnerSingletonInstance {
private static final StaticInnerSingleton instance = new StaticInnerSingleton();
}
private StaticInnerSingleton() {}
public static StaticInnerSingleton getInstance() {
return StaticInnerSingletonInstance.instance;
}
}
5.枚举
/**
* 单例模式-枚举
*/
public enum EnumSingleton {
INSTANCE;
}
单例模式测试
1.测试
/**
* 测试五种方式实现单例
*/
public class Client1 {
public static void main(String[] args) {
EagerSingleton e1 = EagerSingleton.getInstance();
EagerSingleton e2 = EagerSingleton.getInstance();
System.out.println(e1 == e2);
LazySingleton l1 = LazySingleton.getInstance();
LazySingleton l2 = LazySingleton.getInstance();
System.out.println(l1 == l2);
DoubleCheckSingleton d1 = DoubleCheckSingleton.getInstance();
DoubleCheckSingleton d2 = DoubleCheckSingleton.getInstance();
System.out.println(d1 == d2);
StaticInnerSingleton s1 = StaticInnerSingleton.getInstance();
StaticInnerSingleton s2 = StaticInnerSingleton.getInstance();
System.out.println(s1 == s2);
EnumSingleton en1 = EnumSingleton.INSTANCE;
EnumSingleton en2 = EnumSingleton.INSTANCE;
System.out.println(en1 == en2);
}
}
2.测试效率
/**
* 测试单例五种方式效率
*/
public class Client2 {
public static void main(String[] args) throws InterruptedException {
Long start = System.currentTimeMillis();
int threadNum = 10;
final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
for(int i=0;i<threadNum;i++){
new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<1000000;i++){
// Object o = EagerSingleton.getInstance(); // 耗时52ms
// Object o = LazySingleton.getInstance(); // 耗时342ms
// Object o = DoubleCheckSingleton.getInstance(); // 耗时55ms
// Object o = StaticInnerSingleton.getInstance(); // 耗时54ms
// Object o = EnumSingleton.INSTANCE; // 耗时46ms
}
countDownLatch.countDown();
}
}).start();
}
countDownLatch.await();
long end = System.currentTimeMillis();
System.out.println("总耗时:"+(end-start));
}
}
3.测试破解
/**
* 通过反射和反序列化方式破解单例
*/
public class Client3 {
public static void main(String[] args) throws Exception {
//通过反射方式构造多个对象
Class<EagerSingletonHack> clazz = (Class<EagerSingletonHack> )Class.forName("cn.dfun.pattern.singleton.EagerSingletonHack");
Constructor<EagerSingletonHack> c = clazz.getDeclaredConstructor();
// 构造器设为可见
c.setAccessible(true);
EagerSingletonHack e1 = c.newInstance();
EagerSingletonHack e2 = c.newInstance();
System.out.println(e1 == e2);
//通过反序列化的方式构造多个对象
EagerSingletonHack e3 = EagerSingletonHack.getInstance();
FileOutputStream fos = new FileOutputStream("d:/a.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(e3);
oos.close();
fos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/a.txt"));
EagerSingletonHack e4 = (EagerSingletonHack) ois.readObject();
System.out.println(e3 == e4);
}
}
防破解
/**
* 单例模式防破解
*/
public class EagerSingletonHack implements Serializable {
private static EagerSingletonHack instance = new EagerSingletonHack();
/**
* 私有化构造器
*/
private EagerSingletonHack() {
// 防止反射方式破解
if(instance!=null){
throw new RuntimeException();
}
}
public static EagerSingletonHack getInstance() {
return instance;
}
/**
* 反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象!
* @return
* @throws ObjectStreamException
*/
private Object readResolve() throws ObjectStreamException {
return instance;
}
}
2 工厂模式
使用工厂类创建对象代替new
简单工厂模式
定义Car接口
public interface Car {
void run();
}
两个具体实现类
public class Audi implements Car{
@Override
public void run() {
System.out.println("Audi run...");
}
}
public class Benz implements Car{
@Override
public void run() {
System.out.println("Benz run...");
}
}
工厂类根据类型参数返回具体的实现类
public class CarFactory {
public static Car createCar(String type) {
if("Audi".equals(type)) {
return new Audi();
} else if("Benz".equals(type)) {
return new Benz();
} else {
return null;
}
}
}
客户端只需与工厂类和接口交互
public class Client {
public static void main(String[] args) {
Car c1 = CarFactory.createCar("Audi");
Car c2 = CarFactory.createCar("Benz");
c1.run();
c2.run();
}
}
工厂方法模式
多个不同工厂类实现相同工厂接口
Car接口与实现类与1相同
工厂接口
public interface CarFactory {
Car createCar();
}
两个工厂实现类
public class AudiFactory implements CarFactory{
@Override
public Car createCar() {
return new Audi();
}
}
public class BenzFactory implements CarFactory{
@Override
public Car createCar() {
return new Benz();
}
}
客户端
public class Client {
public static void main(String[] args) {
Car c1 = new AudiFactory().createCar();
Car c2 = new BenzFactory().createCar();
c1.run();
c2.run();
}
}
抽象工厂模式
生产不同产品族的所有产品
引擎接口及高配低配两个实现类
public interface Engine {
void run();
}
class LuxuryEngine implements Engine {
@Override
public void run() {
System.out.println("高配引擎");
}
}
class LowEngine implements Engine {
@Override
public void run() {
System.out.println("低配引擎");
}
}
座椅接口及低配高配两个实现类
public interface Seat {
void massage();
}
class LuxurySeat implements Seat {
@Override
public void massage() {
System.out.println("高配座椅");
}
}
class LowSeat implements Seat {
@Override
public void massage() {
System.out.println("低配座椅");
}
}
工厂接口及高配低配两个工厂实现类
高配工厂创建高配引擎和座椅
低配工厂创建低配引擎和座椅
public interface CarFactory {
Seat createSeat();
Engine createEngine();
}
class LuxuryCarFactory implements CarFactory {
@Override
public Seat createSeat() {
return new LuxurySeat();
}
@Override
public Engine createEngine() {
return new LuxuryEngine();
}
}
class LowCarFactory implements CarFactory {
@Override
public Seat createSeat() {
return new LowSeat();
}
@Override
public Engine createEngine() {
return new LowEngine();
}
}
客户端
public class Client {
public static void main(String[] args) {
CarFactory factory = new LuxuryCarFactory();
Engine e = factory.createEngine();
e.run();
CarFactory factory2 = new LowCarFactory();
Seat s = factory2.createSeat();
s.massage();
}
}
3 建造者模式
复杂对象子组件构建和装配分离
飞艇类,包含轨道舱\引擎\逃逸塔三个组件
public class Airship {
//轨道舱
private OrbitalModule orbitalModule;
//发动机
private Engine engine;
//逃逸塔
private EscapeTower escapeTower;
public OrbitalModule getOrbitalModule() {
return orbitalModule;
}
public void setOrbitalModule(OrbitalModule orbitalModule) {
this.orbitalModule = orbitalModule;
}
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public EscapeTower getEscapeTower() {
return escapeTower;
}
public void setEscapeTower(EscapeTower escapeTower) {
this.escapeTower = escapeTower;
}
}
class OrbitalModule {
private String name;
public OrbitalModule(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Engine {
private String name;
public Engine(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class EscapeTower {
private String name;
public EscapeTower(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
构建器接口
public interface AirshipBuilder {
Engine builderEngine();
OrbitalModule builderOrbitalModule();
EscapeTower builderEscapeTower();
}
装配器接口
public interface AirshipDirector {
Airship directAirship();
}
构建器实现类
public class DfunAirshipBuilder implements AirshipBuilder{
@Override
public Engine builderEngine() {
System.out.println("构建dfun发动机!");
return new Engine("dfun发动机!");
}
@Override
public OrbitalModule builderOrbitalModule() {
System.out.println("构建dfun轨道舱!");
return new OrbitalModule("dfun轨道舱!");
}
@Override
public EscapeTower builderEscapeTower() {
System.out.println("构建dfun逃逸塔!");
return new EscapeTower("dfun逃逸塔!");
}
}
装配器实现类
public class DfunAirshipDirector implements AirshipDirector{
private AirshipBuilder builder;
public DfunAirshipDirector(AirshipBuilder builder) {
this.builder = builder;
}
@Override
public Airship directAirship() {
Engine e = builder.builderEngine();
OrbitalModule o = builder.builderOrbitalModule();
EscapeTower et = builder.builderEscapeTower();
//装配成飞船对象
Airship ship = new Airship();
ship.setEngine(e);
ship.setEscapeTower(et);
ship.setOrbitalModule(o);
return ship;
}
}
客户端
public class Client {
public static void main(String[] args) {
AirshipDirector director = new DfunAirshipDirector(new DfunAirshipBuilder());
Airship ship = director.directAirship();
System.out.println(ship.getEngine().getName());
}
}
4 原型模式
原型模式用于拷贝对象,克隆对象属性值与原对象相同
spring bean的创建方式就两种:单例和原型
public class Sheep implements Cloneable, Serializable {
private String sname;
private Date birthday;
@Override
protected Object clone() throws CloneNotSupportedException {
// 直接调用Object对象的clone方法实现克隆
Object obj = super.clone();
// 深复制
Sheep s = (Sheep) obj;
s.birthday = (Date) this.birthday.clone();
return obj;
}
getter/setter/有参无参构造器
}
测试深复制/浅复制
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Date d = new Date(123123123123L);
Sheep s1 = new Sheep("多利", d);
Sheep s2 = (Sheep)s1.clone();
// 克隆出的对象与原型对象属性值相同
System.out.println(s2.getSname());
// 浅克隆,日期为同一对象
System.out.println(d == s2.getBirthday());
}
}
使用序列化和反序列化的方式实现深克隆
public class Client2 {
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
Date d = new Date(123123123123L);
Sheep s1 = new Sheep("多利", d);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(s1);
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
Sheep s2 = (Sheep) ois.readObject();
// 深复制,日期不同
System.out.println(d == s2.getBirthday());
}
}
原型模式效率测试
对象new过程比较耗时,使用原型模型可以显著提升效率
public class Client3 {
public static void testNew(int size) throws InterruptedException {
long start = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
Laptop t = new Laptop();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
public static void testClone(int size) throws InterruptedException, CloneNotSupportedException {
long start = System.currentTimeMillis();
Laptop t = new Laptop();
for (int i = 0; i < size; i++) {
Laptop temp = (Laptop) t.clone();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
testNew(1000);
testClone(1000);
}
}
class Laptop implements Cloneable{
Laptop() throws InterruptedException {
// 模拟创建对象耗时
Thread.sleep(10);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
5 适配器模式
场景:USB转换头
将一个类的接口转为客户希望的另一个接口,使原本不兼容的类可以一起工作
被适配的类
public class Adaptee {
public void request() {
System.out.println("可以完成客户需要的功能");
}
}
接口
public interface Target {
void handleReq();
}
适配器
/**
* 适配器
* 两种关联方式1.继承 2.持有被适配对象引用
* @author Vincent
*/
public class Adapter implements Target{
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void handleReq() {
adaptee.request();
}
}
客户端
public class Client {
public void test(Target t) {
t.handleReq();
}
public static void main(String[] args) {
Client client = new Client();
Adaptee adaptee = new Adaptee();
Target t = new Adapter(adaptee);
client.test(t);
}
}
场景:
java中流的转换
6 静态代理模式
代理模式:
控制对对象的访问,调用对象方法前做前置处理,调用对象方法后做后置处理
代理模式是AOP的核心
场景:
安全代理,屏蔽真实角色的直接访问
远程代理,通过代理类处理远程方法调用(RMI)
延迟加载,先加载轻量级代理对象,真正需要时再加载真实对象
动态代理:
动态生成代理类
JDK自带动态代理\javaassist字节码操作库\CGLIB\ASM(底层指令维护性差)
接口
public interface Star {
/**面谈*/
void confer();
/**签合同*/
void signContract();
/**订票*/
void bookTicket();
/**唱歌*/
void sing();
/**收尾款*/
void collectMoney();
}
真实类
public class RealStar implements Star{
@Override
public void confer() {
System.out.println("RealStar confer");
}
@Override
public void signContract() {
System.out.println("RealStar signContract");
}
@Override
public void bookTicket() {
System.out.println("RealStar bookTicket");
}
@Override
public void sing() {
System.out.println("RealStar sing");
}
@Override
public void collectMoney() {
System.out.println("RealStar collectMoney");
}
}
代理类
public class ProxyStar implements Star{
// 持有真实类的引用
private Star star;
public ProxyStar(Star star) {
this.star = star;
}
@Override
public void confer() {
System.out.println("ProxyStar confer");
}
@Override
public void signContract() {
System.out.println("ProxyStar signContract");
}
@Override
public void bookTicket() {
System.out.println("ProxyStar bookTicket");
}
@Override
public void sing() {
// 调用真实类的方法
star.sing();
}
@Override
public void collectMoney() {
System.out.println("ProxyStar collectMoney");
}
}
客户端
public class Client {
public static void main(String[] args) {
Star real = new RealStar();
Star proxy = new ProxyStar(real);
proxy.confer();
// 代理类调用真实类的方法
proxy.sing();
}
}
7 动态代理模式
jdk自带动态代理:
java.lang.reflect.Proxy
动态生成代理类和对象
java.lang.reflect.InvocationHandler
处理器接口
通过invoke方法实现对真实角色的代理访问
每次通过Proxy生成代理类对象都要指定对应的处理器对象
接口
public interface Star {
/**唱歌*/
void sing();
}
真实对象
public class RealStar implements Star{
@Override
public void sing() {
System.out.println("RealStar sing");
}
}
处理器对象
public class StarHandler implements InvocationHandler {
Star realStar;
public StarHandler(Star realStar) {
this.realStar = realStar;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 每次调代理类方法都进到该方法,可进行统一流程控制
Object object = null;
System.out.println("面谈...签合同...订机票...");
if(method.getName().equals("sing")) {
object = method.invoke(realStar, args);
}
System.out.println("收尾款...");
return object;
}
}
客户端
public class Client {
public static void main(String[] args) {
Star realStar = new RealStar();
StarHandler handler = new StarHandler(realStar);
Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler);
proxy.sing();
}
}
场景:
Struts2拦截器
数据库连接池关闭
Hibernate延迟加载
mybatis拦截器插件
AspectJ
spring aop 日志/声明式事务
web service
RMI
随便选择一个技术框架都有代理模式
8 桥接模式
类膨胀问题
联想笔记本 联想台式机 联想平板
华为笔记本 华为台式机 华为平板
...
通过电脑持有品牌对象实现桥接
/**
* 品牌
*/
public interface Brand {
void sale();
}
class Lenovo implements Brand {
@Override
public void sale() {
System.out.println("销售联想电脑");
}
}
class Dell implements Brand {
@Override
public void sale() {
System.out.println("销售戴尔电脑");
}
}
public class Computer {
// 持有品牌对象
protected Brand brand;
public Computer(Brand brand) {
this.brand = brand;
}
public void sale() {
brand.sale();
}
}
class Desktop extends Computer {
public Desktop(Brand brand) {
super(brand);
}
@Override
public void sale() {
System.out.println("销售台式机");
}
}
class Laptop extends Computer {
public Laptop(Brand brand) {
super(brand);
}
@Override
public void sale() {
System.out.println("销售笔记本");
}
}
public class Client {
public static void main(String[] args) {
// 销售联想笔记本
// 用组合代替集成关系
Computer computer = new Laptop(new Lenovo());
computer.sale();
}
}
场景(多个变化维度):
JDBC
银行日志管理两个维度
格式分类 操作 交易 异常
距离分类 本地 异地
人力资源系统奖金计算
奖金分类 个人 团体 激励
部门分类 人事 销售 研发
OA消息处理
业务类型 普通 加急 特急
发送方式 系统内 短信 邮件
9 组合模式
场景
部分和整体关系用树状结构表示,从而客户端可以使用统一的方式处理部分和整体对象
模拟杀毒软件架构设计
public interface AbstractFile {
void killVirus();
}
class ImageFile implements AbstractFile {
private String name;
public ImageFile(String name) {
this.name = name;
}
@Override
public void killVirus() {
System.out.println("图像文件 " + name + " 进行查杀");
}
}
class TextFile implements AbstractFile {
private String name;
public TextFile(String name) {
this.name = name;
}
@Override
public void killVirus() {
System.out.println("文本文件 " + name + " 进行查杀");
}
}
class Folder implements AbstractFile {
private String name;
// 定义容器,用来存放容器子节点
private List<AbstractFile> list = new ArrayList<>();
public Folder(String name) {
this.name = name;
}
public void add(AbstractFile file) {
list.add(file);
}
public void remove(AbstractFile file) {
list.remove(file);
}
public AbstractFile getChild(int index) {
return list.get(index);
}
@Override
public void killVirus() {
System.out.println("文件夹 " + name + " 进行查杀");
for(AbstractFile file : list) {
// 天然递归
file.killVirus();
}
}
}
客户端
public class Client {
public static void main(String[] args) {
AbstractFile f2, f3, f5, f6;
Folder f1 = new Folder("我的收藏");
f2 = new ImageFile("头像.jpg");
f3 = new TextFile("1.txt");
f1.add(f2);
f1.add(f3);
// f1.killVirus();
// f2.killVirus();
Folder f4 = new Folder("图像");
f5 = new ImageFile("1.jpg");
f6 = new ImageFile("2.jpg");
f4.add(f5);
f4.add(f6);
f1.add(f4);
f1.killVirus();
}
}
应用
操作系统资源管理器
GUI容器层次图
XML文件解析
OA组织结构处理
Junit单元测试框架
10 装饰器模式
动态地为一个对象增加新的功能
无需继承增加子类,使用对象的关联关系,避免类膨胀
/**
* 抽象组件
*/
public interface ICar {
void move();
}
/**
* 具体构建对象
*/
class Car implements ICar {
@Override
public void move() {
System.out.println("陆地上跑");
}
}
/**
* 装饰器对象
*/
class SuperCar implements ICar {
protected ICar car;
public SuperCar(ICar car) {
this.car = car;
}
@Override
public void move() {
car.move();
}
}
class FlyCar extends SuperCar {
public FlyCar(ICar car) {
super(car);
}
public void fly() {
System.out.println("飞");
}
@Override
public void move() {
super.move();
fly();
}
}
class WaterCar extends SuperCar {
public WaterCar(ICar car) {
super(car);
}
public void swim() {
System.out.println("游");
}
@Override
public void move() {
super.move();
swim();
}
}
class AICar extends SuperCar {
public AICar(ICar car) {
super(car);
}
public void autoMove() {
System.out.println("自动驾驶");
}
@Override
public void move() {
super.move();
autoMove();
}
}
客户端
public class Client {
public static void main(String[] args) {
Car car = new Car();
car.move();
// 增加飞行功能
FlyCar flyCar = new FlyCar(car);
flyCar.move();
// 增加水里游功能(复合功能)
WaterCar waterCar = new WaterCar(flyCar);
waterCar.move();
}
}
应用
IO流
Servlet API中Request对象HttpServletRequestWrapper(关键词Wrapper)
缺点
产生很多小对象,影响性能
易于出错,调试麻烦
装饰模式和桥接模式区别
桥接模式是沿多个维度变化,装饰模式是增加新功能
11 外观(门面)模式
迪米特法则:
一个实体应尽量少地与其他实体发生相互作用
public class Gongshang {
public void kaihu() {
System.out.println("工商局开户");
}
}
public class Shuiwu {
public void baoshui() {
System.out.println("税务局报税");
}
}
public class Yinhang {
public void kaihu() {
System.out.println("银行开户");
}
}
门面对象
public class RegisterFacade {
public void register() {
Gongshang gongshang = new Gongshang();
gongshang.kaihu();
Yinhang yinhang = new Yinhang();
yinhang.kaihu();
Shuiwu shuiwu = new Shuiwu();
shuiwu.baoshui();
}
}
客户端
/**
* 客户端只与门面对象打交道
*/
public class Client {
public static void main(String[] args) {
RegisterFacade registerFacade = new RegisterFacade();
registerFacade.register();
}
}
各种框架都会用到:
commons提供的DBUtils类
Hibernate提供的工具类
Spring JDBC工具类
12 享元模式
很多个相同或相似对象通过享元模式节省内存
高效支持大量细粒度对象重用
场景
围棋棋子,内部状态(颜色)共享,外部状态(坐标)作为参数传入
/**
* 享元类
*/
public interface ChessFlyWeight {
void setColor(String color);
String getColor();
void display(Coordinate c);
}
class ConcreteChess implements ChessFlyWeight {
private String color;
public ConcreteChess(String color) {
this.color = color;
}
@Override
public void setColor(String color) {
this.color = color;
}
@Override
public String getColor() {
return color;
}
@Override
public void display(Coordinate c) {
System.out.println("棋子颜色:" + color);
System.out.println("棋子坐标:" + c.getX() + "," + c.getY());
}
}
public class Coordinate {
private int x, y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
享元工厂
/**
* 享元工厂类
*/
public class ChessFlyWeightFactory {
// 享元池
private static Map<String, ChessFlyWeight> map = new HashMap<>();
public static ChessFlyWeight getChess(String color) {
if(map.get(color) != null) {
return map.get(color);
} else {
ChessFlyWeight chessFlyWeight = new ConcreteChess(color);
map.put(color, chessFlyWeight);
return chessFlyWeight;
}
}
}
客户端
public class Client {
public static void main(String[] args) {
ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");
System.out.println(chess1 == chess2);
// 增加外部状态处理
chess1.display(new Coordinate(10, 10));
chess2.display(new Coordinate(20, 20));
}
}
应用
线程池 数据库连接池
String类的设计(共享常量池)
13 责任链模式
行为模式关注对象交互
责任链模式将能够处理同一请求的对象连成链
场景
打牌轮流出牌
公司公文审批
/**
* 封装请假基本信息
*/
public class LeaveRequest {
private String empName;
private int leaveDays;
private String reason;
// 有参构造器/getter/setter...
}
责任链
关系可以实时修改
/**
* 抽象类
*/
public abstract class Leader {
protected String name;
protected Leader nextLeader;
public Leader(String name) {
this.name = name;
}
/**
* 设置责任链后继对象
* @param nextLeader
*/
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
/**
* 处理请求的核心业务方法
* @param leaveRequest
*/
public abstract void handleRequest(LeaveRequest leaveRequest);
}
class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getLeaveDays() < 3) {
System.out.println("员工:" + leaveRequest.getEmpName() +
"请假, 天数:"+leaveRequest.getLeaveDays());
System.out.println("主任:" + this.name + "审批通过");
} else if(this.nextLeader != null) {
this.nextLeader.handleRequest(leaveRequest);
}
}
}
class Manager extends Leader {
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getLeaveDays() >= 3 && leaveRequest.getLeaveDays() < 10) {
System.out.println("员工:" + leaveRequest.getEmpName() +
"请假, 天数:"+leaveRequest.getLeaveDays());
System.out.println("经理:" + this.name + "审批通过");
} else if(this.nextLeader != null) {
this.nextLeader.handleRequest(leaveRequest);
}
}
}
class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getLeaveDays() >= 10) {
System.out.println("员工:" + leaveRequest.getEmpName() +
"请假, 天数:"+leaveRequest.getLeaveDays());
System.out.println("总经理:" + this.name + "审批通过");
} else if(this.nextLeader != null) {
System.out.println("辞退!");
}
}
}
客户端
public class Client {
public static void main(String[] args) {
Leader a = new Director("张三");
Leader b = new Manager("李四");
Leader c = new GeneralManager("王五");
a.setNextLeader(b);
b.setNextLeader(c);
LeaveRequest leaveRequest = new LeaveRequest("Tom", 10, "相亲");
a.handleRequest(leaveRequest);
}
}
通过集合\数组生成责任链更加实用
应用:
异常机制
js事件冒泡和捕获机制
Servlet过滤器
Struts2拦截器
14 迭代器(游标 cursor)模式
场景
提供一种可以遍历聚合对象的方式
/**
* 自定义迭代器接口
*/
public interface MyIterator {
void first();
void next();
boolean hasNext();
boolean isFirst();
boolean isLast();
Object getCurrent();
}
/**
* 自定义聚合类
*/
public class ConcreteMyAggregate {
private List<Object> list = new ArrayList<>();
/**
* 获得迭代器
* @return
*/
public MyIterator createIterator() {
return new ConcreteIterator();
}
public void addObj(Object obj) {
list.add(obj);
}
public void removeObj(Object obj) {
list.remove(obj);
}
public List<Object> getList() {
return list;
}
public void setList(List<Object> list) {
this.list = list;
}
private class ConcreteIterator implements MyIterator {
private int curcor;
@Override
public void first() {
curcor = 0;
}
@Override
public void next() {
if(curcor < list.size()) {
curcor++;
}
}
@Override
public boolean hasNext() {
if(curcor < list.size()) {
return true;
}
return false;
}
@Override
public boolean isFirst() {
return curcor == 0 ? true : false;
}
@Override
public boolean isLast() {
return curcor == list.size()-1 ? true : false;
}
@Override
public Object getCurrent() {
return list.get(curcor);
}
}
}
public class Client {
public static void main(String[] args) {
ConcreteMyAggregate concreteMyAggregate = new ConcreteMyAggregate();
concreteMyAggregate.addObj("aa");
concreteMyAggregate.addObj("bb");
concreteMyAggregate.addObj("cc");
MyIterator iter = concreteMyAggregate.createIterator();
while(iter.hasNext()) {
System.out.println(iter.getCurrent());
iter.next();
}
}
}
应用
Java Set/List的迭代器
网友评论