23种设计模式之Java实现
来源:互联网 发布:马刺队史数据 编辑:程序博客网 时间:2024/06/16 21:45
单例模式之饿汉式
class SingletonDemo1 { private static SingletonDemo1 instance = new SingletonDemo1() ; //类初始化时,立即加载,天然线程安全 private SingletonDemo1() {} //私有化构造器 public static SingletonDemo1 getInstance() { //不需要同步,调用效率高 return instance ; }}
单例模式之懒汉式
class SingletonDemo2 { private static SingletonDemo2 instance = null ; //类初始化时,不初始化这个对象,延迟加载,真正用的时候再创建 private SingletonDemo2() {} //私有化构造器 public static synchronized SingletonDemo2 getInstance() { //需要同步,调用效率低 if(instance == null) { instance = new SingletonDemo2() ; } return instance ; }}
单例模式之静态内部类实现
class SingletonDemo3 { //外部类初始化时,不会初始化这个静态类,延迟加载,真正用的时候再创建 private static class SingletonClassInstance { //类初始化时,立即加载,天然线程安全 private static final SingletonDemo3 instance = new SingletonDemo3() ; } private SingletonDemo3() {} //私有化构造器 //不需要同步,调用效率高 public static SingletonDemo3 getInstance() { return SingletonClassInstance.instance ; }}
单例模式之枚举实现
enum SingletonDemo4 { //枚举元素本身就是单例对象,由JVM保证,避免通过反射和反序列化的漏洞,但是不能延迟加载 INSTANCE ; //根据需要,添加额外的操作 public void singletonOperation() { }}
单例模式总结:不需要延迟加载,枚举的方式好于饿汉式;需要延迟加载,静态内部类的方式好于懒汉式。
但是以上实现方式,除了 枚举 的方式外,其余都可以通过 反射 和 反序列化 的方式破解。测试代码如下:
package JavaDesignPattern;import java.io.*;import java.lang.reflect.Constructor;public class SingletonDemo { public static void main(String[] args) throws Exception { SingletonDemo1 s1 = SingletonDemo1.getInstance() ; SingletonDemo1 s2 = SingletonDemo1.getInstance() ; System.out.println(s1) ; System.out.println(s2) ; Class<SingletonDemo1> clazz = (Class<SingletonDemo1>)Class.forName("JavaDesignPattern.SingletonDemo1") ; Constructor<SingletonDemo1> c = clazz.getDeclaredConstructor(null) ; c.setAccessible(true) ; SingletonDemo1 s3 = c.newInstance() ; SingletonDemo1 s4 = c.newInstance() ; System.out.println(s3) ; System.out.println(s4) ; ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt")) ; oos.writeObject(s1) ; ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt")) ; SingletonDemo1 s5 = (SingletonDemo1) ois.readObject() ; System.out.println(s5) ; }}
输出如下:
JavaDesignPattern.SingletonDemo1@56de9984JavaDesignPattern.SingletonDemo1@56de9984JavaDesignPattern.SingletonDemo1@3030d5aaJavaDesignPattern.SingletonDemo1@561ba49dJavaDesignPattern.SingletonDemo1@29e0969b
那么问题来了,如何避免通过 反射 和 反序列化 的方式破解呢?解决方法如下:
class SingletonDemo1 implements Serializable{ private static SingletonDemo1 instance = new SingletonDemo1() ; //类初始化时,立即加载,天然线程安全 private SingletonDemo1() { //私有化构造器 if(instance != null) { //阻止反射 throw new RuntimeException() ; } } public static SingletonDemo1 getInstance() { //不需要同步,调用效率高 return instance ; } //反序列化时,如果定义了readResolve(),则直接返回此方法指定的对象,而不是单独创建新对象。 private Object readResolve() throws ObjectStreamException { return instance ; }}
简单工厂模式(静态工厂模式)
interface Car{ void run() ;}class Audi implements Car { @Override public void run() { System.out.println("奥迪!") ; }}class Byd implements Car { @Override public void run() { System.out.println("比亚迪~~") ; }}class CarFactory1{ public static Car createCar(String type) { if(type.equals("奥迪")) { return new Audi() ; }else if(type.equals("比亚迪")) { return new Byd() ; }else { return null ; } }}
工厂方法模式
interface Car{ void run() ;}class Audi implements Car { @Override public void run() { System.out.println("奥迪!") ; }}class Byd implements Car { @Override public void run() { System.out.println("比亚迪~~") ; }}interface CarFactory2{ Car createCar() ;}class AudiFactory implements CarFactory2 { @Override public Car createCar() { return new Audi() ; }}class BydFactory implements CarFactory2 { @Override public Car createCar() { return new Byd() ; }}
抽象工厂模式
interface Motor { void run() ; void start() ;}class LuxuruMotor implements Motor { @Override public void run() { System.out.println("做功快!") ; } @Override public void start() { System.out.println("启动快,可以自动启停!") ; }}class LowMotor implements Motor { @Override public void run() { System.out.println("做功慢!") ; } @Override public void start() { System.out.println("启动慢!") ; }}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("符合人体工程学,但不能自动按摩!") ; }}interface Tyre{ void roll() ;}class LuxuryTyre implements Tyre { @Override public void roll() { System.out.println("耐磨!") ; }}class LowTyre implements Tyre { @Override public void roll() { System.out.println("容易磨损!") ; }}interface CarFactory3 { Motor createMotor () ; Seat createSeat() ; Tyre createTyre() ;}class LuxuryCarFactory implements CarFactory3 { @Override public Motor createMotor() { return new LuxuruMotor() ; } @Override public Seat createSeat() { return new LuxurySeat() ; } @Override public Tyre createTyre() { return new LuxuryTyre() ; }}class LowCarFactory implements CarFactory3 { @Override public Motor createMotor() { return new LowMotor() ; } @Override public Seat createSeat() { return new LowSeat() ; } @Override public Tyre createTyre() { return new LowTyre() ; }}
测试代码如下:
package JavaDesignPattern;public class Factory { public static void main(String[] args) { Car c1 = CarFactory1.createCar("奥迪") ; Car c2 = CarFactory1.createCar("比亚迪") ; c1.run() ; c2.run() ; Car c3 = new AudiFactory().createCar() ; Car c4 = new BydFactory().createCar() ; c3.run() ; c4.run() ; Motor e = new LuxuryCarFactory().createMotor() ; e.run() ; e.start() ; Seat s = new LuxuryCarFactory().createSeat() ; s.massage() ; Tyre t = new LuxuryCarFactory().createTyre() ; t.roll() ; }}
工厂模式总结:
- 简单工厂模式又叫静态工厂模式,就是工厂类一般使用静态方法,通过接受参数的不同来返回不同的对象实例。对于新产品的增加,如果不修改已有源代码的话,是无法扩展的。虽然这违反了开闭原则(OCP),但是实际使用最多。
- 工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展。
- 抽象工厂模式:不可以增加产品,只可以增加产品族。
建造者模式
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 ; }}class AirShip { private OrbitalModule orbitalModule ; private Engine engine ; private EscapeTower escapeTower ; public void launch() { System.out.println("点火发射!") ; } 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 ; }}interface AirShipBuilder { OrbitalModule buildOrbitalModule() ; Engine buildEngine() ; EscapeTower buildEscapeTower() ;}class NASAAirShipBuilder implements AirShipBuilder { @Override public OrbitalModule buildOrbitalModule() { System.out.println("NASA轨道舱") ; return new OrbitalModule("NASA轨道舱"); } @Override public Engine buildEngine() { System.out.println("NASA引擎") ; return new Engine("NASA引擎"); } @Override public EscapeTower buildEscapeTower() { System.out.println("NASA逃逸塔") ; return new EscapeTower("NASA逃逸塔") ; }}interface AirShipDirector { AirShip directAirShip() ;}class NASAAirShipDirector implements AirShipDirector { private AirShipBuilder builder ; public NASAAirShipDirector(AirShipBuilder builder) { this.builder = builder; } @Override public AirShip directAirShip() { AirShip ship = new AirShip() ; ship.setOrbitalModule(builder.buildOrbitalModule()) ; ship.setEngine(builder.buildEngine()) ; ship.setEscapeTower(builder.buildEscapeTower()) ; return ship ; }}
测试代码如下:
package JavaDesignPattern;public class Builder { public static void main(String[] args) { AirShip ship = new NASAAirShipDirector(new NASAAirShipBuilder()).directAirShip() ; System.out.println(ship.getEngine().getName()) ; ship.launch() ; }}
建造者模式总结:实现了构建和装配的解耦。应用场景:某些对象的构建过程非常复杂。
原型模式
class Sheep implements Cloneable, Serializable{ private Date birthday ; private String sname ; public Sheep() {} public Sheep(Date birthday, String sname) { this.birthday = birthday; this.sname = sname; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone() ; //浅复制 return obj ; }}
测试代码如下:
package JavaDesignPattern;import java.io.Serializable;import java.util.Date;public class ProtoType { public static void main(String[] args) throws Exception { Date d = new Date(1490758473000L) ; Sheep s1 = new Sheep(d, "多莉") ; Sheep s2 = (Sheep) s1.clone() ; System.out.println(s1.getSname()) ; System.out.println(s1.getBirthday()) ; System.out.println(s1) ; d.setTime(1490759999000L) ; System.out.println(s1.getBirthday()) ; System.out.println(s2.getSname()) ; System.out.println(s2.getBirthday()) ; System.out.println(s2) ; }}
输出如下:
多莉Wed Mar 29 11:34:33 CST 2017JavaDesignPattern.Sheep@633835b4Wed Mar 29 11:59:59 CST 2017多莉Wed Mar 29 11:59:59 CST 2017JavaDesignPattern.Sheep@7f4def4f
不难发现,虽然s2是s1的克隆对象,但是它们共用了一个Date对象,这就是所谓的“浅克隆”。那么如何实现“深克隆”呢?只需要将复写的clone()方法略微修改一下即可。
@Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone() ; //浅复制 Sheep s = (Sheep) obj ; s.birthday = (Date) this.birthday.clone(); //深复制 return obj ; }
再次输出如下:
多莉Wed Mar 29 11:34:33 CST 2017JavaDesignPattern.Sheep@1c4600f0Wed Mar 29 11:59:59 CST 2017多莉Wed Mar 29 11:34:33 CST 2017JavaDesignPattern.Sheep@37e79b10
很显然,成功实现了“深克隆”。
详解Java中的clone方法 – 原型模式
此外,还可以通过序列化、反序列化的方式实现“深克隆”。测试代码如下:
package JavaDesignPattern;import java.io.*;import java.util.Date;public class ProtoType { public static void main(String[] args) throws Exception { Date d = new Date(1490758473000L) ; Sheep s1 = new Sheep(d, "多莉") ; //Sheep s2 = (Sheep) s1.clone() ; System.out.println(s1.getSname()) ; System.out.println(s1.getBirthday()) ; System.out.println(s1) ; ByteArrayOutputStream baos = new ByteArrayOutputStream() ; ObjectOutputStream oos = new ObjectOutputStream(baos) ; oos.writeObject(s1) ; byte[] bytes = baos.toByteArray() ; //序列化为一个数组 ByteArrayInputStream bais = new ByteArrayInputStream(bytes) ; ObjectInputStream ois = new ObjectInputStream(bais) ; Sheep s2 = (Sheep) ois.readObject(); //反序列化 d.setTime(1490759999000L) ; System.out.println(s1.getBirthday()) ; System.out.println(s2.getSname()) ; System.out.println(s2.getBirthday()) ; System.out.println(s2) ; }}
输出如下:
多莉Wed Mar 29 11:34:33 CST 2017JavaDesignPattern.Sheep@559a6cd4Wed Mar 29 11:59:59 CST 2017多莉Wed Mar 29 11:34:33 CST 2017JavaDesignPattern.Sheep@5b611c24
从结果来看,成功实现了“深克隆”。
原型模式总结:通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。原型模式很少单独出现,一般和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。
=====================================================================
至此,创建型模式完结。单例模式、工厂模式、建造者模式、原型模式都属于创建型模式——关注对象的创建过程。
=====================================================================
适配器模式
//被改造者class Adaptee { public void request() { System.out.println("可以完成客户需要的功能") ; }}interface Target { void handleRequest() ;}//对象适配器,采用组合的方式来处理class MyAdapter implements Target { private Adaptee adaptee ; public MyAdapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void handleRequest() { adaptee.request() ; }}
测试代码如下:
package JavaDesignPattern;public class Adapter { public static void main(String[] args) { Adaptee a = new Adaptee() ; Target t = new MyAdapter(a) ; t.handleRequest() ; }}
适配器模式总结:通过包装一个需要适配的对象,把原接口转换成目标接口。
代理模式
interface Star { void confer() ; void signContract() ; void bookTicket() ; void sing() ; void collectMoney() ;}class RealStar implements Star { public RealStar() {} @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()--我的热情好像一把火!") ; } @Override public void collectMoney() { System.out.println("RealStar().collectMoney()") ; }}//静态代理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()") ; }}//动态代理,开发中常见class StarHandler implements InvocationHandler { private Star star ; public StarHandler(Star star) { this.star = star; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.print("######\t") ; method.invoke(star, args) ; return null; }}
测试代码如下:
package JavaDesignPattern;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class Proxy { public static void main(String[] args) { Star real = new RealStar() ; Star sProxy = new ProxyStar(real) ; sProxy.confer(); sProxy.signContract(); sProxy.bookTicket(); sProxy.sing(); sProxy.collectMoney(); StarHandler handler = new StarHandler(real) ; Star dProxy = (Star) java.lang.reflect.Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler) ; dProxy.confer(); dProxy.signContract(); dProxy.bookTicket(); dProxy.sing(); dProxy.collectMoney(); }}
输出如下:
ProxyStar().confer()ProxyStar().signContract()ProxyStar().bookTicket()RealStar()--我的热情好像一把火!ProxyStar().collectMoney()###### RealStar().confer()###### RealStar().signContract()###### RealStar().bookTicket()###### RealStar()--我的热情好像一把火!###### RealStar().collectMoney()
代理模式总结:可以详细控制访问某类或者某个对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。通过代理,控制对 对象 的访问。
桥接模式
interface Brand { void sale() ;}class Dell implements Brand { @Override public void sale() { System.out.println("销售Dell") ; }}class MacBook implements Brand { @Override public void sale() { System.out.println("销售MacBook") ; }}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() { super.sale(); System.out.println("台式机") ; }}class Laptop extends Computer { public Laptop(Brand brand) { super(brand); } @Override public void sale() { super.sale(); System.out.println("笔记本") ; }}
测试代码如下:
package JavaDesignPattern;public class Bridge { public static void main(String[] args) { Computer c1 = new Laptop(new MacBook()) ; c1.sale() ; Computer c2 = new Desktop(new Dell()) ; c2.sale() ; }}
输出如下:
销售MacBook笔记本销售Dell台式机
桥接模式总结:处理多层继承结构,多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展,在抽象层建立关联。
组合模式
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("正在查杀图片文件:\t"+name) ; }}class TextFile implements AbstractFile { private String name ; public TextFile(String name) { this.name = name; } @Override public void killVirus() { System.out.println("正在查杀文本文件:\t"+name) ; }}class VedioFile implements AbstractFile { private String name ; public VedioFile(String name) { this.name = name; } @Override public void killVirus() { System.out.println("正在查杀视频文件:\t"+name) ; }}class Folder implements AbstractFile { private String name ; private java.util.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 getIndex(int index) { return list.get(index) ; } @Override public void killVirus() { System.out.println("正在进入文件夹:\t"+name+"\t查杀") ; for(AbstractFile file : list) { file.killVirus() ; } }}
测试代码如下:
package JavaDesignPattern;import java.util.ArrayList;/** * Created by YZX on 2017/3/31. */public class Composite { public static void main(String[] args) { AbstractFile f2, f3, f4, f5, f7, f8, f9, f10 ; Folder f1 = new Folder("我的文档") ; f2 = new ImageFile("QQ头像") ; f3 = new ImageFile("人人头像") ; f4 = new TextFile("HelloWorld.java") ; f5 = new TextFile("HelloSpark.scala") ; f1.add(f2); f1.add(f3); f1.add(f4); f1.add(f5); Folder f6 = new Folder("我的电影") ; f7 = new VedioFile("射雕英雄") ; f8 = new VedioFile("神雕侠侣") ; f9 = new VedioFile("倚天屠龙") ; f10 = new VedioFile("鹿鼎记") ; f6.add(f7); f6.add(f8); f6.add(f9); f6.add(f10); f1.add(f6) ; f1.killVirus() ; }}
输出如下:
正在进入文件夹: 我的文档 查杀正在查杀图片文件: QQ头像正在查杀图片文件: 人人头像正在查杀文本文件: HelloWorld.java正在查杀文本文件: HelloSpark.scala正在进入文件夹: 我的电影 查杀正在查杀视频文件: 射雕英雄正在查杀视频文件: 神雕侠侣正在查杀视频文件: 倚天屠龙正在查杀视频文件: 鹿鼎记
组合模式总结:为部分和整体的树形关系提供了完美的解决方案,从而可以使用统一的方式处理部分对象和整体对象。其中,使用了递归调用的机制对整个树形结构进行处理。
装饰模式
interface ICar { void move() ;}//具体构建角色(真实对象)class ConcreteCar implements ICar { public ConcreteCar() {} @Override public void move() { System.out.println("陆地巡洋舰") ; }}//Decorator装饰角色class SuperCar implements ICar { private ICar icar ; public SuperCar(ICar icar) { this.icar = icar; } @Override public void move() { icar.move() ; }}//ConcreteDecorator具体装饰角色class FlyCar extends SuperCar { public FlyCar(ICar icar) { super(icar); } private void fly() { System.out.println("天上飞") ; } @Override public void move() { super.move(); fly(); }}//ConcreteDecorator具体装饰角色class WaterCar extends SuperCar { public WaterCar(ICar icar) { super(icar); } private void swim() { System.out.println("水上漂") ; } @Override public void move() { super.move(); swim(); }}//ConcreteDecorator具体装饰角色class AICar extends SuperCar { public AICar(ICar icar) { super(icar); } private void autoMove() { System.out.println("自动驾驶") ; } @Override public void move() { super.move(); autoMove(); }}
测试代码如下:
package JavaDesignPattern;public class Decorator { public static void main(String[] args) { ConcreteCar car = new ConcreteCar() ; car.move(); System.out.println("------------------------") ; new FlyCar(car).move(); System.out.println("------------------------") ; new WaterCar(car).move(); System.out.println("------------------------") ; new AICar(car).move(); System.out.println("------------------------") ; new AICar(new WaterCar(new FlyCar(car))).move() ; }}
输出如下:
陆地巡洋舰------------------------陆地巡洋舰天上飞------------------------陆地巡洋舰水上漂------------------------陆地巡洋舰自动驾驶------------------------陆地巡洋舰天上飞水上漂自动驾驶
装饰模式总结:装饰模式是一种用于代替继承的技术,不需要通过继承增加子类就能扩展对象的新功能(动态地为一个对象增加功能)。使用对象的 关联关系 代替继承关系,更加灵活,同时避免类型体系的快速膨胀。
外观模式
class FacadeRegister { public FacadeRegister() {} public void register() { new 海淀工商局().checkName(); new 海淀税务局().taxCertificate(); new 中国招商银行().openAccount(); new 海淀质检局().orgCodeCertificate(); }}interface 工商局 { void checkName() ;}class 海淀工商局 implements 工商局 { public 海淀工商局() {} @Override public void checkName() { System.out.println("公司名是否存在冲突") ; }}interface 税务局 { void taxCertificate() ;}class 海淀税务局 implements 税务局 { public 海淀税务局() {} @Override public void taxCertificate() { System.out.println("在海淀税务局办理税务登记证") ; }}interface 银行 { void openAccount() ;}class 中国招商银行 implements 银行 { public 中国招商银行() {} @Override public void openAccount() { System.out.println("在中国招商银行开户") ; }}interface 质检局 { void orgCodeCertificate() ;}class 海淀质检局 implements 质检局 { public 海淀质检局() {} @Override public void orgCodeCertificate() { System.out.println("在海淀质检局办理组织机构代码证") ; }}
测试代码如下:
package JavaDesignPattern;public class Facade { public static void main(String[] args) {// 工商局 a = new 海淀工商局() ;// a.checkName();// 税务局 b = new 海淀税务局() ;// b.taxCertificate();// 银行 c = new 中国招商银行() ;// c.openAccount();// 质检局 d = new 海淀质检局() ;// d.orgCodeCertificate(); new FacadeRegister().register(); }}
外观模式总结:封装子系统的复杂性,为子系统提供统一的入口,便于客户端调用。
享元模式
//外部状态,非共享享元类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; }}//享元类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("棋子位置:\t[ "+c.getX()+" , "+c.getY()+" ]\t棋子颜色:\t"+color) ; }}class ChessFlyWeightFactory { //享元池 private static java.util.HashMap<String, ChessFlyWeight> map = new java.util.HashMap<>() ; public static ChessFlyWeight getChess(String color) { if(map.get(color) != null) { return map.get(color) ; }else { ChessFlyWeight cfw = new ConcreteChess(color) ; map.put(color, cfw) ; return cfw ; } }}
测试代码如下:
package JavaDesignPattern;public class FlyWeight { public static void main(String[] args) { ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("black") ; ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("black") ; System.out.println(chess1) ; System.out.println(chess2) ; chess1.disPlay(new Coordinate(10, 10)); chess2.disPlay(new Coordinate(15, 15)); ChessFlyWeight chess3 = ChessFlyWeightFactory.getChess("white") ; ChessFlyWeight chess4 = ChessFlyWeightFactory.getChess("white") ; System.out.println(chess3) ; System.out.println(chess4) ; chess3.disPlay(new Coordinate(20, 20)); chess4.disPlay(new Coordinate(25, 25)); }}
输出如下:
JavaDesignPattern.ConcreteChess@55fa12f6JavaDesignPattern.ConcreteChess@55fa12f6棋子位置: [ 10 , 10 ] 棋子颜色: black棋子位置: [ 15 , 15 ] 棋子颜色: blackJavaDesignPattern.ConcreteChess@1f4790beJavaDesignPattern.ConcreteChess@1f4790be棋子位置: [ 20 , 20 ] 棋子颜色: white棋子位置: [ 25 , 25 ] 棋子颜色: white
享元模式总结:相似或者相同对象内存中只存一份,极大减少内存中对象的数量,提高系统性能。外部状态相对独立,不影响内部状态。
=====================================================================
**至此,结构型模式完结。适配模式、代理模式、桥接模式、组合模式、装饰模式、外观模式
、享元模式都属于结构型模式——关注对象和类的组织。**
=====================================================================
责任链模式
//请假的基本信息class LeaveRequest { private String name ; private int days ; private String reason ; public LeaveRequest(String name, int days, String reason) { this.name = name; this.days = days; this.reason = reason; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getDays() { return days; } public void setDays(int days) { this.days = days; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; }}abstract class Leader { protected String name ; protected Leader leader ; //责任链上的后继对象 public Leader(String name) { this.name = name; } public void setLeader(Leader leader) { this.leader = leader; } public abstract void handleRequest(LeaveRequest request) ;}class Director extends Leader { public Director(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.getDays() < 3) { System.out.println(request.getName()+"\t请假\t"+request.getDays()+"\t天,原因:\t"+request.getReason()+"。\t审批人:\t"+this.name+"\t主任") ; }else { if(this.leader != null) { this.leader.handleRequest(request) ; } } }}class Manager extends Leader { public Manager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.getDays() < 10) { System.out.println(request.getName()+"\t请假\t"+request.getDays()+"\t天,原因:\t"+request.getReason()+"。\t审批人:\t"+this.name+"\t经理") ; }else { if(this.leader != null) { this.leader.handleRequest(request) ; } } }}class GeneralManager extends Leader { public GeneralManager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.getDays() < 30) { System.out.println(request.getName()+"\t请假\t"+request.getDays()+"\t天,原因:\t"+request.getReason()+"。\t审批人:\t"+this.name+"\t总经理") ; }else { System.out.println("批准\t"+request.getName()+"\t辞职。\t审批人:\t"+this.name+"\t总经理") ; } }}
测试代码如下:
package JavaDesignPattern;public class ChainOfResponsibility { public static void main(String[] args) { Leader a = new Director("张") ; Leader b = new Manager("李") ; Leader c = new GeneralManager("王") ; a.setLeader(b); b.setLeader(c); LeaveRequest request1 = new LeaveRequest("Tom", 2, "看病") ; a.handleRequest(request1); LeaveRequest request2 = new LeaveRequest("John", 10, "结婚") ; a.handleRequest(request2); LeaveRequest request3 = new LeaveRequest("Carlo", 30, "旅游") ; a.handleRequest(request3); }}
输出如下:
Tom 请假 2 天,原因: 看病。 审批人: 张 主任John 请假 10 天,原因: 结婚。 审批人: 王 总经理批准 Carlo 辞职。 审批人: 王 总经理
责任链模式总结:将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该要求,如果能责处理,否则传递给链上的下一个对象。
迭代器模式
interface MyIterator { Object first() ; Object next() ; boolean isFirst() ; boolean hasNext() ; boolean isLast() ;}class ConcreteMyAggregate { private List<Object> list = new ArrayList<>() ; public ConcreteMyAggregate() {} public List<Object> getList() { return list; } public void setList(List<Object> list) { this.list = list; } public void addObject(Object object) { list.add(object) ; } public void removeObject(Object object) { list.remove(object) ; } //内部类可以直接使用外部类的属性 private class ConcreIterator implements MyIterator { private int cursor ; @Override public Object first() { return list.get(0) ; } @Override public Object next() { return list.get(cursor++) ; } @Override public boolean isFirst() { return cursor == 0 ; } @Override public boolean hasNext() { return cursor <= (list.size()-1) ; } @Override public boolean isLast() { return cursor == (list.size()-1) ; } } //获得迭代器 public MyIterator createIterator() { return new ConcreIterator() ; }}
测试代码如下:
package JavaDesignPattern;import java.util.ArrayList;import java.util.List;public class IteratorPattern { public static void main(String[] args) { ConcreteMyAggregate cma = new ConcreteMyAggregate() ; cma.addObject("bb"); cma.addObject("hh"); cma.addObject("jj"); MyIterator iter = cma.createIterator() ; while(iter.hasNext()) { System.out.println(iter.next()) ; } }}
输出如下:
bbhhjj
迭代器模式总结:提供一种遍历聚合对象的方式,又称为游标(cursor)模式。
中介者模式
interface Mediator { void register(String name, Department d) ; void command(String name) ;}interface Department { void selfAction() ; void outAction() ;}class DevelopDepartment implements Department { private Mediator m ; public DevelopDepartment(Mediator m) { this.m = m ; m.register("DevelopDepartment", this) ; } @Override public void selfAction() { System.out.println("专心研发项目") ; } @Override public void outAction() { System.out.println("汇报工作:发工资、申请资金支持") ; m.command("FinacialDepartment") ; }}class FinacialDepartment implements Department { private Mediator m ; public FinacialDepartment(Mediator m) { this.m = m ; m.register("FinacialDepartment", this) ; } @Override public void selfAction() { System.out.println("数钱") ; } @Override public void outAction() { System.out.println("汇报工作:没钱了、钱太多怎么花?") ; }}class MarketDepartment implements Department { private Mediator m ; public MarketDepartment(Mediator m) { this.m = m ; m.register("MarketDepartment", this) ; } @Override public void selfAction() { System.out.println("出去拉项目") ; } @Override public void outAction() { System.out.println("汇报工作:项目进度、申请资金支持") ; m.command("FinacialDepartment"); }}class President implements Mediator { private Map<String, Department> map = new HashMap<>() ; @Override public void register(String name, Department d) { map.put(name, d) ; } @Override public void command(String name) { map.get(name).selfAction() ; }}
测试代码如下:
package JavaDesignPattern;import java.util.HashMap;import java.util.Map;public class MediatorPattern { public static void main(String[] args) { Mediator m = new President() ; MarketDepartment market = new MarketDepartment(m) ; DevelopDepartment develop = new DevelopDepartment(m) ; FinacialDepartment finacial = new FinacialDepartment(m) ; market.selfAction(); market.outAction(); }}
输出如下:
出去拉项目汇报工作:项目进度、申请资金支持数钱
中介者模式总结:解耦多个同事对象之间的交互关系。每个对象都持有中介者对象的引用,只跟中介者对象打交道,通过中介者对象统一管理这些交互关系。
命令模式
//真正的命令执行者class Receiver { public void action() { System.out.println("Receiver.action()") ; }}interface Command { void execute() ;}class ConcreteCommand implements Command { private Receiver receiver ; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { //命令真正执行前后,做相关的处理。 receiver.action(); }}//发起者class Invoker { //也可以通过List<Command>容纳很多命令对象进行命令批处理。数据库底层的事务管理就是类似的结构 private Command command ; public Invoker(Command command) { this.command = command; } //业务方法,用于调用命令类的方法 public void call() { command.execute(); }}
测试代码如下:
package JavaDesignPattern;public class CommandPattern { public static void main(String[] args) { Command c = new ConcreteCommand(new Receiver()) ; Invoker invoker = new Invoker(c) ; invoker.call(); }}
命令模式总结:将一个请求封装为一个对象,对请求排队或者记录请求日志,以及支持可撤销的操作,也被称为事务模式。
解释器模式
访问者模式
策略模式
interface Strategy { double getPrice(double standardPrice) ;}class NewCustomerFewStrategy implements Strategy { public NewCustomerFewStrategy() {} @Override public double getPrice(double standardPrice) { System.out.println("普通客户小批量不打折") ; return standardPrice ; }}class NewCustomerManyStrategy implements Strategy { public NewCustomerManyStrategy() {} @Override public double getPrice(double standardPrice) { System.out.println("普通客户大批量打9折") ; return standardPrice*0.9 ; }}class OldCustomerFewStrategy implements Strategy { public OldCustomerFewStrategy() {} @Override public double getPrice(double standardPrice) { System.out.println("老客户大批量打85折") ; return standardPrice*0.85 ; }}class OldCustomerManyStrategy implements Strategy { public OldCustomerManyStrategy() {} @Override public double getPrice(double standardPrice) { System.out.println("老客户大批量打8折") ; return standardPrice*0.8 ; }}//负责和具体的策略交互class Context { private Strategy strategy ; public Context(Strategy strategy) { this.strategy = strategy; } public void setStrategy(Strategy strategy) { this.strategy = strategy; } public void printPrice(double standardPrice) { System.out.println("报价:\t"+strategy.getPrice(standardPrice)) ; }}
测试代码如下:
package JavaDesignPattern;public class StrategyPattern { public static void main(String[] args) { new Context(new NewCustomerFewStrategy()).printPrice(3998); new Context(new NewCustomerManyStrategy()).printPrice(3998); new Context(new OldCustomerFewStrategy()).printPrice(3998); new Context(new OldCustomerManyStrategy()).printPrice(3998); }}
输出如下:
普通客户小批量不打折报价: 3998.0普通客户大批量打9折报价: 3598.2000000000003老客户大批量打85折报价: 3398.2999999999997老客户大批量打8折报价: 3198.4
策略模式总结:策略模式对应于解决某一个问题的算法族,容许用户从该算法族中任选一个算法解决某一个问题,同时可以方便的更换算法或者增加新的算法。本质:分离算法,选择实现。
模版方法模式
abstract class BankTemplateMethod { public final void takeNumber() { System.out.println("取号排队") ; } public abstract void transact() ; public final void evaluate() { System.out.println("反馈评分") ; } public final void process() { this.takeNumber(); this.transact(); this.evaluate(); }}class DrawMoney extends BankTemplateMethod { @Override public void transact() { System.out.println("我要理财") ; }}
测试代码如下:
package JavaDesignPattern;public class TemplateMethod { public static void main(String[] args) { BankTemplateMethod btm1 = new DrawMoney() ; btm1.process(); //匿名内部类 BankTemplateMethod btm2 = new BankTemplateMethod() { @Override public void transact() { System.out.println("我要办储蓄卡") ; } }; btm2.process(); }}
输出如下:
取号排队我要理财反馈评分取号排队我要办储蓄卡反馈评分
模版方法模式总结:处理某个流程的代码都已经具备,但是其中某个节点的代码暂时不能确定,将这个节点的代码实现转移给子类完成。
状态模式
interface State { void handle() ;}class FreeState implements State { public FreeState() {} @Override public void handle() { System.out.println("房间空闲") ; }}class BookedState implements State { public BookedState() {} @Override public void handle() { System.out.println("房间已被预定") ; }}class CheckedInState implements State { public CheckedInState() {} @Override public void handle() { System.out.println("房间已入住") ; }}class StateContext { private State state ; public StateContext() {} public void setState(State state) { this.state = state ; state.handle() ; }}
测试代码如下:
package JavaDesignPattern;public class StatePattern { public static void main(String[] args) { StateContext sc = new StateContext() ; sc.setState(new FreeState()); sc.setState(new BookedState()); sc.setState(new CheckedInState()); }}
输出如下:
房间空闲房间已被预定房间已入住
状态模式总结:用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。例如:线程对象各状态之间的切换。
观察者模式
interface Observer { void update(Subject subject) ;}class ObserverA implements Observer { //myState需要跟目标对象的state值保持一致 private int myState ; public int getMyState() { return myState; } public void setMyState(int myState) { this.myState = myState; } @Override public void update(Subject subject) { myState = ((ConcreteSubjectA) subject).getState() ; }}/*--------------------------------------------------------------------*/class ObserverB implements java.util.Observer { private int myState ; public int getMyState() { return myState; } public void setMyState(int myState) { this.myState = myState; } @Override public void update(java.util.Observable o, Object arg) { myState = ((ConcreteSubjectB)o).getState() ; }}/*--------------------------------------------------------------------*/class Subject { private List<Observer> list = new ArrayList<Observer>() ; public void addObserver(Observer observer) { list.add(observer) ; } public void removeObserver(Observer observer) { list.remove(observer) ; } public void notifyAllObserver() { for(Observer obs : list) { obs.update(this) ; } }}class ConcreteSubjectA extends Subject { private int state ; public int getState() { return state; } public void setState(int state) { this.state = state; this.notifyAllObserver(); }}/*--------------------------------------------------------------------*/class ConcreteSubjectB extends java.util.Observable { private int state ; public int getState() { return state; } public void setState(int state) { this.state = state; //目标对象已经做了更改 setChanged(); //通知所有的观察者 notifyObservers(this.state); }}/*--------------------------------------------------------------------*/
测试代码如下:
package JavaDesignPattern;import java.util.ArrayList;import java.util.List;public class ObserverPattern { public static void main(String[] args) { ConcreteSubjectA csa = new ConcreteSubjectA() ; ObserverA a1 = new ObserverA() ; ObserverA a2 = new ObserverA() ; ObserverA a3 = new ObserverA() ; csa.addObserver(a1); csa.addObserver(a2); csa.addObserver(a3); csa.setState(3998); System.out.println(csa.getClass().getName()+"\t"+a1.getMyState()) ; System.out.println(csa.getClass().getName()+"\t"+a2.getMyState()) ; System.out.println(csa.getClass().getName()+"\t"+a3.getMyState()) ; ConcreteSubjectB csb = new ConcreteSubjectB() ; ObserverB b1 = new ObserverB() ; ObserverB b2 = new ObserverB() ; ObserverB b3 = new ObserverB() ; csb.addObserver(b1); csb.addObserver(b2); csb.addObserver(b3); csb.setState(1998); System.out.println(csb.getClass().getName()+"\t"+b1.getMyState()) ; System.out.println(csb.getClass().getName()+"\t"+b2.getMyState()) ; System.out.println(csb.getClass().getName()+"\t"+b3.getMyState()) ; }}
输出如下:
JavaDesignPattern.ConcreteSubjectA 3998JavaDesignPattern.ConcreteSubjectA 3998JavaDesignPattern.ConcreteSubjectA 3998JavaDesignPattern.ConcreteSubjectB 1998JavaDesignPattern.ConcreteSubjectB 1998JavaDesignPattern.ConcreteSubjectB 1998
观察者模式总结:观察者模式主要用于1:N的通知。当一个目标对象的状态发生改变时,它需要及时告知一系列观察者对象,令其作出响应。典型应用场景:广播机制。
备忘录模式
//源发器类class Emp { private String name ; private int age ; private double salary ; public Emp(String name, int age, double salary) { this.name = name; this.age = age; this.salary = salary; } //进行备忘操作,并且返回备忘录对像 public EmpMemento memento() { return new EmpMemento(this) ; } //进行数据恢复,恢复成指定备忘录的值 public void recovery(EmpMemento em) { this.name = em.getName() ; this.age = em.getAge() ; this.salary = em.getSalary() ; } 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 double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; }}//备忘录类class EmpMemento { private String name ; private int age ; private double salary ; public EmpMemento(Emp e) { this.name = e.getName() ; this.age = e.getAge() ; this.salary = e.getSalary() ; } 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 double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; }}//负责人类class CareTaker { private EmpMemento em ; //private Stack<EmpMemento> stack = new Stack<>() ; //设置多个备忘点 public EmpMemento getEm() { return em; } public void setEm(EmpMemento em) { this.em = em; }}
测试代码如下:
package JavaDesignPattern;public class MementoPattern { public static void main(String[] args) { CareTaker ct = new CareTaker() ; Emp emp = new Emp("Madara", 26, 12000) ; System.out.println("第1次:\t"+emp.getName()+"----"+emp.getAge()+"----"+emp.getSalary()) ; ct.setEm(emp.memento()); emp.setName("Uchiha"); emp.setAge(35); emp.setSalary(50000); System.out.println("第2次:\t"+emp.getName()+"----"+emp.getAge()+"----"+emp.getSalary()) ; emp.recovery(ct.getEm()); System.out.println("第3次:\t"+emp.getName()+"----"+emp.getAge()+"----"+emp.getSalary()) ; }}
输出如下:
第1次: Madara----26----12000.0第2次: Uchiha----35----50000.0第3次: Madara----26----12000.0
备忘录模式总结:保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先的状态。应用场景:普通软件中的撤销操作,数据库中事务的回滚操作。
=====================================================================
至此,行为型模式完结。行为型模式——关注系统中对象之间的相互交互,研究系统运行时对象之间的相互通信和协作,进一步明确对象的职责,共有11种模式。
=====================================================================
- 23种设计模式之Java实现
- 23种设计模式之创建模式....(java实现)
- 设计模式之适配器模式(三种实现) JAVA
- 设计模式之组合模式java实现
- 设计模式之适配器模式Java实现
- Java实现设计模式之工厂模式
- Java实现设计模式之外观模式
- Java实现设计模式之策略模式
- Java实现设计模式之观察者模式
- Java实现设计模式之适配器模式
- 设计模式之装饰模式Java实现
- 23种设计模式之python实现
- 23种经典设计模式的java实现之生成器模式
- 23种设计模式之单例模式(java 实现)
- 23种设计模式 - java 实现
- 23种设计模式及java实现
- 设计模式 之 Singleton(Java实现)
- Java设计模式之代码实现
- KMP算法的改进
- javascript 数组以及对象的深拷贝的方法
- 炫酷的glsurfaceview
- 主席树-poj2104
- MyBatis分页插件PageHelper的使用
- 23种设计模式之Java实现
- Redis实战教程
- 异或加密
- thrift安装
- 406错误 java
- Ardupilot -- APM源码笔记三(重制)~ 传感器驱动程序
- 指针和数组比较
- Android PopupMenu弹出菜单使用
- leetcode 44. Wildcard Matching