设计模式 设计模式是为了让程序具有更好的可读性、 可靠性、 可扩展性、 代码重用性, 使程序呈现高内聚、 低耦合的特性。
软件设计原则
单一职责原则: 一个类只负责一项职责( 并不是一个方法) , 如果逻辑简单, 类中方法少, 可以在方法级别保持单一职责原则。
接口隔离原则: 一个类对另一个类的依赖应该建立在最小的接口上。
开闭原则: 它是最基础, 最重要的设计原则。 软件模块方法和函数应该对扩展( 提供方) 开放对修改( 使用方) 关闭, 用抽象构建框架, 用实现扩展细节。
里氏替换原则: 所有引用基类的地方必须能透明地使用其子类对象, 尽量少使用继承, 采用依赖, 聚合, 组合等关系代替。
依赖倒转原则: 底层模块尽量有抽象类或接口, 或者两个都有。 变量的声明类型尽量是抽象类或接口。
迪米特法则: 核心是降低类之间的耦合, 对自己依赖的类知道的越少越好。
合成复用原则: 尽量使用合成/聚合的方式, 不使用继承。
类的关系与UML类图
依赖( 虚线加箭头)
关联( 实线加箭头)
实现( 虚线加三角形)
泛化/继承( 实线加三角形)
聚合( 实线加实心菱形)
组合( 实线加空心菱形)
创建者模式 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式, 而不是使用 new 运算符直接实例化对象。 这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
单例模式 单例模式( Singleton Pattern) 是 Java 中最简单的设计模式之一。 这种类型的设计模式属于创建型模式, 它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类, 该类负责创建自己的对象, 同时确保只有单个对象被创建。 这个类提供了一种访问其唯一的对象的方式, 可以直接访问, 不需要实例化该类的对象。
饿汉式( 静态常量)
私有化构造器
在类的内部创建一个静态常量的对象实例
提供一个静态的共有方法获取实例
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 Singleton { private Singleton () {} private static final Singleton instance = new Singleton (); public static Singleton getInstance () { return instance; } } public class Test { public static void main (String[] args) { Singleton instance1 = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); System.out.println(instance1.hashCode()); System.out.println(instance2.hashCode()); } }
懒汉式( 线程不安全)
私有化构造器
在类的内部定义一个静态对象
提供一个静态的公有方法
判断对象为空则创建对象返回, 对象不为空则直接返回
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 public class Singleton { private Singleton () {} private static Singleton instance = null ; public static Singleton getInstance () { if (instance == null ) { instance = new Singleton (); } return instance; } } public class Test { public static void main (String[] args) { Singleton instance1 = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); System.out.println(instance1.hashCode()); System.out.println(instance2.hashCode()); } }
懒汉式( 同步方法, 线程安全)
私有化构造器
在类的内部定义一个静态对象
提供一个静态的公有方法( 方法加同步锁)
判断对象为空则创建对象并返回, 对象不为空则直接返回
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 Singleton { private Singleton () {} private static Singleton instance = null ; public static synchronized Singleton getInstance () { if (instance == null ) { instance = new Singleton (); } return instance; } } public class Test { public static void main (String[] args) { Singleton instance1 = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); System.out.println(instance1.hashCode()); System.out.println(instance2.hashCode()); } }
懒汉式( 双重校检锁)
私有化构造器
在类的内部定义一个静态对象
提供一个静态的公有方法
判断对象是否为空, 不为空直接返回
对象为空, 添加同步锁->再次判断对象是否为空
对象为空则创建对象并返回, 对象不为空则直接返回
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 public class Singleton { private Singleton () {} private static volatile Singleton instance = null ; public static Singleton getInstance () { if (instance == null ) { synchronized (Singleton.class) { if (instance == null ) { instance = new Singleton (); } } } return instance; } } public class Test { public static void main (String[] args) { Singleton instance1 = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); System.out.println(instance1.hashCode()); System.out.println(instance2.hashCode()); } }
懒汉式( 静态内部类)
私有化构造器
在类的内部创建一个私有的静态类, 类中有一个静态常量的对象实例
在外部类中, 提供一个共有的静态方法, 调用该方法时返回静态内部类中的对象实例
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 Singleton { private Singleton () {} private static class SingletonInstance { private static final Singleton INSTANCE = new Singleton (); } public static Singleton getInstance () { return SingletonInstance.INSTANCE; } } public class Test { public static void main (String[] args) { Singleton instance1 = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); System.out.println(instance1.hashCode()); System.out.println(instance2.hashCode()); } }
枚举类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 enum Singleton { INSTANCE; } public class Test { public static void main (String[] args) { Singleton instance1 = Singleton.INSTANCE; Singleton instance2 = Singleton.INSTANCE; System.out.println(instance1.hashCode()); System.out.println(instance2.hashCode()); } }
原型模式 原型模式( Prototype Pattern) 是用于创建重复的对象, 同时又能保证性能。 这种类型的设计模式属于创建型模式, 它提供了一种创建对象的最佳方式之一。
这种模式是实现了一个原型接口, 该接口用于创建当前对象的克隆。 当直接创建对象的代价比较大时, 则采用这种模式。 例如, 一个对象需要在一个高代价的数据库操作之后被创建。 我们可以缓存该对象, 在下一个请求时返回它的克隆, 在需要的时候更新数据库, 以此来减少数据库调用。
浅拷贝
类继承Cloneable接口
实现clone方法
使用clone方法克隆出一个新的对象
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 54 55 56 57 58 59 60 public class Sheep implements Cloneable { private String name; private int age; private Sheep friend; public Sheep (String name, int age, Sheep friend) { this .name = name; this .age = age; this .friend = friend; } public Sheep getFriend () { return friend; } public void setFriend (Sheep friend) { this .friend = friend; } @Override public String toString () { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}' ; } @Override public Sheep clone () { try { return (Sheep) super .clone(); } catch (CloneNotSupportedException e) { throw new AssertionError (); } } } public class Run { public static void main (String[] args) { Sheep harry = new Sheep ("Harry" , 1 , null ); Sheep dolly = new Sheep ("Dolly" , 1 , harry); System.out.println(dolly.toString()); Sheep clone1 = dolly.clone(); Sheep clone2 = dolly.clone(); System.out.println("多莉1号克隆体:" + clone1.hashCode()); System.out.println("多莉2号克隆体:" + clone1.hashCode()); System.out.println(clone1 == clone2); System.out.println("多莉1号克隆体朋友:" + clone1.getFriend().hashCode()); System.out.println("多莉2号克隆体朋友:" + clone2.getFriend().hashCode()); System.out.println(dolly.getFriend() == clone1.getFriend()); System.out.println(clone1.getFriend() == clone2.getFriend()); } }
深拷贝
类继承Cloneable接口和Serializable接口
实现clone方法, 方法中使用序列化, 反序列化返回对象
使用clone方法克隆出一个新的对象
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 public class Sheep implements Cloneable , Serializable { private String name; private int age; private Sheep friend; public Sheep (String name, int age, Sheep friend) { this .name = name; this .age = age; this .friend = friend; } public Sheep getFriend () { return friend; } public void setFriend (Sheep friend) { this .friend = friend; } @Override public String toString () { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}' ; } @Override public Sheep clone () { ByteArrayOutputStream bos = null ; ObjectOutputStream oos = null ; ByteArrayInputStream bis = null ; ObjectInputStream ois = null ; try { bos = new ByteArrayOutputStream (); oos = new ObjectOutputStream (bos); oos.writeObject(this ); bis = new ByteArrayInputStream (bos.toByteArray()); ois = new ObjectInputStream (bis); return (Sheep) ois.readObject(); } catch (Exception e) { e.printStackTrace(); return null ; } finally { try { if (bos != null ) {bos.close();} if (oos != null ) {oos.close();} if (bis != null ) {bis.close();} if (ois != null ) {ois.close();} } catch (Exception e) { e.printStackTrace(); } } } } public class Run { public static void main (String[] args) { Sheep harry = new Sheep ("Harry" , 1 , null ); Sheep dolly = new Sheep ("Dolly" , 1 , harry); System.out.println(dolly.toString()); Sheep clone1 = dolly.clone(); Sheep clone2 = dolly.clone(); System.out.println("多莉1号克隆体:" + clone1.hashCode()); System.out.println("多莉2号克隆体:" + clone1.hashCode()); System.out.println(clone1 == clone2); System.out.println("多莉1号克隆体朋友:" + clone1.getFriend().hashCode()); System.out.println("多莉2号克隆体朋友:" + clone2.getFriend().hashCode()); System.out.println(dolly.getFriend() == clone1.getFriend()); System.out.println(clone1.getFriend() == clone2.getFriend()); } }
简单工厂模式 工厂模式( Factory Pattern) 是 Java 中最常用的设计模式之一。 这种类型的设计模式属于创建型模式, 它提供了一种创建对象的最佳方式。
在工厂模式中, 我们在创建对象时不会对客户端暴露创建逻辑, 并且是通过使用一个共同的接口来指向新创建的对象。
结构
创建一个抽象类/接口
新建几个类, 继承/实现
创建一个工厂类,
工厂类中新建一个静态方法, 根据不同的值返回相对应类的实例
客户端直接使用工厂类调用静态方法, 就可以获取需要的实例
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 public abstract class Color { public String nameCN; public String nameEN; public abstract String getRGBString () ; public abstract String getHexadecimalString () ; } public class Black extends Color { public Black () { nameCN = "黑色" ; nameEN = "black" ; } @Override public String getRGBString () { return nameCN + " " + nameEN + " GRB: " + "255,255,255" ; } @Override public String getHexadecimalString () { return nameCN + " " + nameEN + " 十六进制: " + "#FFFFFF" ; } } public class Blue extends Color { public Blue () { nameCN = "蓝色" ; nameEN = "blue" ; } @Override public String getRGBString () { return nameCN + " " + nameEN + " GRB: " + "0,0,255" ; } @Override public String getHexadecimalString () { return nameCN + " " + nameEN + " 十六进制: " + "#0000FF" ; } } public class Red extends Color { public Red () { nameCN = "红色" ; nameEN = "red" ; } @Override public String getRGBString () { return nameCN + " " + nameEN + " GRB: " + "255,69,0" ; } @Override public String getHexadecimalString () { return nameCN + " " + nameEN + " 十六进制: " + "#FF0000" ; } } public class White extends Color { public White () { nameCN = "白色" ; nameEN = "white" ; } @Override public String getRGBString () { return nameCN + " " + nameEN + " GRB: " + "255,255,255" ; } @Override public String getHexadecimalString () { return nameCN + " " + nameEN + " 十六进制: " + "#FFFFFF" ; } } public enum ColorType { RED, BLUE, BLACK, WHITE } public class ColorFactory { public static Color getColor (ColorType colorType) { if (colorType == null ) return null ; switch (colorType) { case RED: return new Red (); case BLUE: return new Blue (); case BLACK: return new Black (); case WHITE: return new White (); default : return null ; } } } public class Run { public static void main (String[] args) { ColorType[] values = ColorType.values(); for (ColorType colorType : values) { Color color = ColorFactory.getColor(colorType); if (color == null ) return ; String rgbString = color.getRGBString(); System.out.println(rgbString); String hexadecimalString = color.getHexadecimalString(); System.out.println(hexadecimalString); } } }
抽象工厂模式 抽象工厂模式( Abstract Factory Pattern) 是围绕一个超级工厂创建其他工厂。 该超级工厂又称为其他工厂的工厂。 这种类型的设计模式属于创建型模式, 它提供了一种创建对象的最佳方式。
在抽象工厂模式中, 接口是负责创建一个相关对象的工厂, 不需要显式指定它们的类。 每个生成的工厂都能按照工厂模式提供对象。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 public interface Color { public void fill () ; } public class Black implements Color { @Override public void fill () { System.out.println("填充黑色" ); } } public class Blue implements Color { @Override public void fill () { System.out.println("填充蓝色" ); } } public class Red implements Color { @Override public void fill () { System.out.println("填充红色" ); } } public class White implements Color { @Override public void fill () { System.out.println("填充白色" ); } } public enum ColorType { RED, BLUE, BLACK, WHITE } public interface Shape { public void draw () ; } public class Circle implements Shape { @Override public void draw () { System.out.println("绘制圆型" ); } } public class Rectangle implements Shape { @Override public void draw () { System.out.println("绘制长方形" ); } } public class Square implements Shape { @Override public void draw () { System.out.println("绘制正方形" ); } } public class Triangle implements Shape { @Override public void draw () { System.out.println("绘制三角形" ); } } public enum ShapeType { CIRCLE, RECTANGLE, SQUARE, TRIANGLE } public abstract class AbstractFactory { public abstract Shape getShape (ShapeType shapeType) ; public abstract Color getColor (ColorType colorType) ; } public class ColorFactory extends AbstractFactory { @Override public Shape getShape (ShapeType shapeType) { return null ; } @Override public Color getColor (ColorType colorType) { if (colorType == null ) return null ; switch (colorType) { case RED: return new Red (); case BLUE: return new Blue (); case BLACK: return new Black (); case WHITE: return new White (); default : return null ; } } } public class ProducerFactory { public static AbstractFactory getFactory (FactoryType factoryType) { if (factoryType == null ) return null ; switch (factoryType) { case SHAPE: return new ShapeFactory (); case COLOR: return new ColorFactory (); default : return null ; } } } public class ShapeFactory extends AbstractFactory { @Override public Shape getShape (ShapeType shapeType) { if (shapeType == null ) return null ; switch (shapeType) { case CIRCLE: return new Circle (); case RECTANGLE: return new Rectangle (); case SQUARE: return new Square (); case TRIANGLE: return new Triangle (); default : return null ; } } @Override public Color getColor (ColorType colorType) { return null ; } } public enum FactoryType { SHAPE, COLOR } public class Run { public static void main (String[] args) { AbstractFactory shapeFactory = ProducerFactory.getFactory(FactoryType.SHAPE); ShapeType[] shapeTypes = ShapeType.values(); for (ShapeType shapeType: shapeTypes) { Shape shape = shapeFactory.getShape(shapeType); shape.draw(); } AbstractFactory colorFactory = ProducerFactory.getFactory(FactoryType.COLOR); ColorType[] colorTypes = ColorType.values(); for (ColorType colorType: colorTypes) { Color color = colorFactory.getColor(colorType); color.fill(); } Color color = shapeFactory.getColor(ColorType.RED); System.out.println(color); } }
方法工厂模式 方法工厂模式( Method Factory Pattern) , 适用于同一属性产品, 不同的生产工厂。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 public abstract class Car { public String name; public abstract String getCarName () ; } public class BJ30 extends Car { public String name = "BJ30" ; @Override public String getCarName () { return name; } } public class BJ40 extends Car { public String name = "BJ40" ; @Override public String getCarName () { return name; } } public class BJ80 extends Car { private String name = "BJ80" ; @Override public String getCarName () { return name; } } public class BM5X extends Car { public String name = "宝马5X" ; @Override public String getCarName () { return name; } } public class BM7X extends Car { public String name = "宝马7X" ; @Override public String getCarName () { return name; } } public class BM9X extends Car { public String name = "宝马9X" ; @Override public String getCarName () { return name; } } public enum CarType { BM5X, BM7X, BM9X, BJ30, BJ40, BJ80 } public abstract class CarFactory { public abstract Car createCar (CarType carType) ; public static CarFactory getBMFactory () { return new BMFactory (); } public static CarFactory getBJFactory () { return new BJFactory (); } } public class BJFactory extends CarFactory { @Override public Car createCar (CarType carType) { if (carType == null ) return null ; switch (carType) { case BJ30: return new BJ30 (); case BJ40: return new BJ40 (); case BJ80: return new BJ80 (); default : return null ; } } } public class BMFactory extends CarFactory { @Override public Car createCar (CarType carType) { if (carType == null ) return null ; switch (carType) { case BM5X: return new BM5X (); case BM7X: return new BM7X (); case BM9X: return new BM9X (); default : return null ; } } } public class Run { public static void main (String[] args) { CarType[] values = CarType.values(); CarFactory bmFactory = CarFactory.getBMFactory(); for (CarType value : values) { Car car = bmFactory.createCar(value); if (car != null ) { System.out.println(car.getCarName()); } } CarFactory bjFactory = CarFactory.getBJFactory(); for (CarType value : values) { Car car = bjFactory.createCar(value); if (car != null ) { System.out.println(car.getCarName()); } } } }
建造者模式 建造者模式( Builder Pattern) 使用多个简单的对象一步一步构建成一个复杂的对象。 这种类型的设计模式属于创建型模式, 它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。 该 Builder 类是独立于其他对象的。
建造者模式有很多变种, 但是万变不离其宗。
结构
产品
建造者抽象类
建造者实现类
指挥者/调用者(自由组合)
例一 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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 public class Course { private String name; private String ppt; private String video; private String note; private String homework; public String getName () { return name; } public void setName (String name) { this .name = name; } public String getPpt () { return ppt; } public void setPpt (String ppt) { this .ppt = ppt; } public String getVideo () { return video; } public void setVideo (String video) { this .video = video; } public String getNote () { return note; } public void setNote (String note) { this .note = note; } public String getHomework () { return homework; } public void setHomework (String homework) { this .homework = homework; } @Override public String toString () { return "Course{" + "name='" + name + '\'' + ", ppt='" + ppt + '\'' + ", video='" + video + '\'' + ", note='" + note + '\'' + ", homework='" + homework + '\'' + '}' ; } } public interface Builder { Course build () ; } public class CourseBuilder implements Builder { private Course course = new Course (); public CourseBuilder setName (String name) { course.setName(name); return this ; } public CourseBuilder setPpt (String ppt) { course.setPpt(ppt); return this ; } public CourseBuilder setVideo (String video) { course.setVideo(video); return this ; } public CourseBuilder setNote (String note) { course.setNote(note); return this ; } public CourseBuilder setHomework (String homework) { course.setHomework(homework); return this ; } @Override public Course build () { return course; } } public class Run { public static void main (String[] args) { CourseBuilder builder = new CourseBuilder (); builder.setName("Sketch-新建画布" ); builder.setPpt("Sketch-PPT" ); builder.setVideo("Sketch-Video" ); builder.setNote("Sketch-快捷键: A" ); builder.setHomework("课后新建几张Mac不同尺寸的画布" ); System.out.println(builder.build()); CourseBuilder builderSj = new CourseBuilder () .setName("设计模式" ) .setPpt("设计模式PPT" ) .setVideo("设计模式视频" ) .setNote("设计模式笔记" ) .setHomework("设计模式课后作业" ); System.out.println(builderSj.build()); } }
例二 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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 public class Computer { private String name; private String mainBoard; private String computerChip; private String graphicsCard; private String memoryModule; private String displayScreen; public String getName () { return name; } public void setName (String name) { this .name = name; } public String getMainBoard () { return mainBoard; } public void setMainBoard (String mainBoard) { this .mainBoard = mainBoard; } public String getComputerChip () { return computerChip; } public void setComputerChip (String computerChip) { this .computerChip = computerChip; } public String getGraphicsCard () { return graphicsCard; } public void setGraphicsCard (String graphicsCard) { this .graphicsCard = graphicsCard; } public String getMemoryModule () { return memoryModule; } public void setMemoryModule (String memoryModule) { this .memoryModule = memoryModule; } public String getDisplayScreen () { return displayScreen; } public void setDisplayScreen (String displayScreen) { this .displayScreen = displayScreen; } @Override public String toString () { return "Computer{" + "name='" + name + '\'' + ", mainBoard='" + mainBoard + '\'' + ", computerChip='" + computerChip + '\'' + ", graphicsCard='" + graphicsCard + '\'' + ", memoryModule='" + memoryModule + '\'' + ", displayScreen='" + displayScreen + '\'' + '}' ; } } public abstract class Builder { protected Computer computer = new Computer (); public abstract Builder setName (String name) ; public abstract Builder setMainBoard (String mainBoard) ; public abstract Builder setComputerChip (String computerChip) ; public abstract Builder setGraphicsCard (String graphicsCard) ; public abstract Builder setMemoryModule (String memoryModule) ; public abstract Builder setDisplayScreen (String displayScreen) ; public Computer build () { return computer; }; } public class HpBuilder extends Builder { @Override public Builder setName (String name) { computer.setName(name); return this ; } @Override public Builder setMainBoard (String mainBoard) { System.out.println("去惠普代工厂拿: " + mainBoard); computer.setMainBoard(mainBoard); return this ; } @Override public Builder setComputerChip (String computerChip) { System.out.println("去惠普代工厂拿: " + computerChip); computer.setComputerChip(computerChip); return this ; } @Override public Builder setGraphicsCard (String graphicsCard) { System.out.println("去惠普代工厂拿: " + graphicsCard); computer.setGraphicsCard(graphicsCard); return this ; } @Override public Builder setMemoryModule (String memoryModule) { System.out.println("去惠普代工厂拿: " + memoryModule); computer.setMemoryModule(memoryModule); return this ; } @Override public Builder setDisplayScreen (String displayScreen) { System.out.println("去惠普代工厂拿: " + displayScreen); computer.setDisplayScreen(displayScreen); return this ; } } public class MacBuilder extends Builder { @Override public Builder setName (String name) { computer.setName(name); return this ; } @Override public Builder setMainBoard (String mainBoard) { System.out.println("去Mac代工厂拿: " + mainBoard); computer.setMainBoard(mainBoard); return this ; } @Override public Builder setComputerChip (String computerChip) { System.out.println("去Mac代工厂拿: " + computerChip); computer.setComputerChip(computerChip); return this ; } @Override public Builder setGraphicsCard (String graphicsCard) { System.out.println("去Mac代工厂拿: " + graphicsCard); computer.setGraphicsCard(graphicsCard); return this ; } @Override public Builder setMemoryModule (String memoryModule) { System.out.println("去Mac代工厂拿: " + memoryModule); computer.setMemoryModule(memoryModule); return this ; } @Override public Builder setDisplayScreen (String displayScreen) { System.out.println("去Mac代工厂拿: " + displayScreen); computer.setDisplayScreen(displayScreen); return this ; } } public class Director { Builder builder = null ; public Director (Builder builder) { this .builder = builder; } public void setBuilder (Builder builder) { this .builder = builder; } public Computer buyComputer (String name, String mainBoard, String computerChip, String graphicsCard, String memoryModule, String displayScreen) { builder.setName(name); builder.setMainBoard(mainBoard); builder.setComputerChip(computerChip); builder.setGraphicsCard(graphicsCard); builder.setMemoryModule(memoryModule); builder.setDisplayScreen(displayScreen); return builder.build(); } } public class Run { public static void main (String[] args) { HpBuilder hpBuilder = new HpBuilder (); Director director = new Director (hpBuilder); Computer hp = director.buyComputer("暗夜精灵" , "惠普主板" , "i9" , "RTX2060" , "16G" , "17英寸" ); System.out.println(hp.toString()); MacBuilder macBuilder = new MacBuilder (); director.setBuilder(macBuilder); Computer mac = director.buyComputer("MacBookPro" , "Apple主板" , "M2" , "16核神经网络引擎" , "16G" , "14 英寸 Liquid 视网膜 XDR 显示屏²" ); System.out.println(mac.toString()); } }
例三 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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 public abstract class House { public String door; public String window; public String yard; public String getDoor () { return door; } public void setDoor (String door) { this .door = door; } public String getWindow () { return window; } public void setWindow (String window) { this .window = window; } public String getYard () { return yard; } public void setYard (String yard) { this .yard = yard; } @Override public String toString () { return "House{" + "door='" + door + '\'' + ", window='" + window + '\'' + ", yard='" + yard + '\'' + '}' ; } } public class CommonHouse extends House { public void other () { System.out.println("其他功能" ); } } public class VillaHouse extends House { public void fun () { System.out.println("别墅特殊功能" ); } } public abstract class Builder { public abstract Builder setDoor (String door) ; public abstract Builder setWindow (String window) ; public abstract Builder setYard (String yard) ; public abstract Object build () ; } public class CommonHouseBuilder extends Builder { private CommonHouse commonHouse; public CommonHouseBuilder () { this .commonHouse = new CommonHouse (); } @Override public Builder setDoor (String door) { commonHouse.setDoor(door); return this ; } @Override public Builder setWindow (String window) { commonHouse.setWindow(window); return this ; } @Override public Builder setYard (String yard) { commonHouse.setYard(yard); return this ; } @Override public CommonHouse build () { return commonHouse; } } public class VillaHouseBuilder extends Builder { private VillaHouse villaHouse; public VillaHouseBuilder () { villaHouse = new VillaHouse (); } @Override public Builder setDoor (String door) { villaHouse.setDoor(door); return this ; } @Override public Builder setWindow (String window) { villaHouse.setWindow(window); return this ; } @Override public Builder setYard (String yard) { villaHouse.setYard(yard); return this ; } @Override public VillaHouse build () { return villaHouse; } } public class Director { private Builder builder; public Director (Builder builder) { this .builder = builder; } public void buildHouse_2D_4W_1Y () { builder.setDoor("两个门" ).setWindow("四个窗" ).setYard("一个院子" ); } public void buildHouse_4D_8W_2Y () { builder.setDoor("四个门" ).setWindow("八个窗" ).setYard("两个院子" ); } } public class Run { public static void main (String[] args) { CommonHouseBuilder commonHouseBuilder = new CommonHouseBuilder (); Director director = new Director (commonHouseBuilder); director.buildHouse_2D_4W_1Y(); CommonHouse commonHouse = commonHouseBuilder.build(); System.out.println(commonHouse.toString()); commonHouse.other(); VillaHouseBuilder villaHouseBuilder = new VillaHouseBuilder (); Director director1 = new Director (villaHouseBuilder); director1.buildHouse_4D_8W_2Y(); VillaHouse villaHouse = villaHouseBuilder.build(); System.out.println(villaHouse.toString()); villaHouse.fun(); } }
结构型模式 这些设计模式关注类和对象的组合。 继承的概念被用来组合接口和定义组合对象获得新功能的方式。
适配器模式 适配器模式( Adapter Pattern) 是作为两个不兼容的接口之间的桥梁。 这种类型的设计模式属于结构型模式, 它结合了两个独立接口的功能。
这种模式涉及到一个单一的类, 该类负责加入独立的或不兼容的接口功能。 举个真实的例子, 读卡器是作为内存卡和笔记本之间的适配器。 您将内存卡插入读卡器, 再将读卡器插入笔记本, 这样就可以通过笔记本来读取内存卡。
类适配器模式
适配器类继承被适配者类
适配器类转化被适配者类中的方法
使用者类调用适配器类中的方法获取想要的值
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 Voltage220V { public int output220V () { System.out.println("输出220V电压" ); return 220 ; } } public interface Voltage5V { public int output5v () ; } public class VoltageAdapter extends Voltage220V implements Voltage5V { @Override public int output5v () { int srcV = output220V(); int dstV = srcV / 44 ; System.out.println("转化为5V的电压" ); return dstV; } } public class mobilePhone { public void charging (Voltage5V voltage5V) { if (voltage5V.output5v() == 5 ){ System.out.println("手机开始充电..." ); } } } public class Run { public static void main (String[] args) { mobilePhone mobilePhone = new mobilePhone (); mobilePhone.charging(new VoltageAdapter ()); } }
对象适配器模式
适配器类聚合被适配者类
适配器类转化被适配者类中的方法
使用者类获取适配器类的实例时传入被适配器类的实例
使用者类调用适配器类中的方法获取想要的值
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 public class Voltage220V { public int output220V () { System.out.println("输出220V电压" ); return 220 ; } } public interface Voltage5V { public int output5v () ; } public class VoltageAdapter implements Voltage5V { private Voltage220V voltage220V; public VoltageAdapter (Voltage220V voltage220V) { this .voltage220V = voltage220V; } @Override public int output5v () { if (voltage220V == null ) return 0 ; int srcV = voltage220V.output220V(); int dstV = srcV / 44 ; System.out.println("转化为5V的电压" ); return dstV; } } public class mobilePhone { public void charging (Voltage5V voltage5V) { if (voltage5V.output5v() == 5 ){ System.out.println("手机开始充电..." ); } } } public class Run { public static void main (String[] args) { mobilePhone mobilePhone = new mobilePhone (); mobilePhone.charging(new VoltageAdapter (new Voltage220V ())); } }
接口适配器模式
某一个接口中有很多方法, 但是只想用其中一个或几个
创建一个抽象类实现接口的全部方法, 空方法即可
实例化抽象类, 重写想要使用的方法即可
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 public interface AdvancedMediaPlayer { public void playVlc (String fileName) ; public void playMp4 (String fileName) ; } public class Mp4Player implements AdvancedMediaPlayer { @Override public void playVlc (String fileName) { } @Override public void playMp4 (String fileName) { System.out.println("Playing mp4 file. Name: " + fileName); } } public class VlcPlayer implements AdvancedMediaPlayer { @Override public void playVlc (String fileName) { System.out.println("Playing vlc file. Name: " + fileName); } @Override public void playMp4 (String fileName) { } } public interface MediaPlayer { public void play (String audioType, String fileName) ; } public class MediaAdapter implements MediaPlayer { AdvancedMediaPlayer advancedMusicPlayer; public MediaAdapter (String audioType) { if (audioType.equalsIgnoreCase("vlc" ) ){ advancedMusicPlayer = new VlcPlayer (); } else if (audioType.equalsIgnoreCase("mp4" )){ advancedMusicPlayer = new Mp4Player (); } } @Override public void play (String audioType, String fileName) { if (audioType.equalsIgnoreCase("vlc" )){ advancedMusicPlayer.playVlc(fileName); }else if (audioType.equalsIgnoreCase("mp4" )){ advancedMusicPlayer.playMp4(fileName); } } } public class AudioPlayer implements MediaPlayer { MediaAdapter mediaAdapter; @Override public void play (String audioType, String fileName) { if (audioType.equalsIgnoreCase("mp3" )){ System.out.println("Playing mp3 file. Name: " + fileName); } else if (audioType.equalsIgnoreCase("vlc" ) || audioType.equalsIgnoreCase("mp4" )){ mediaAdapter = new MediaAdapter (audioType); mediaAdapter.play(audioType, fileName); } else { System.out.println("Invalid media. " + audioType + " format not supported" ); } } } public class Run { public static void main (String[] args) { AudioPlayer audioPlayer = new AudioPlayer (); audioPlayer.play("mp3" , "beyond the horizon.mp3" ); audioPlayer.play("mp4" , "alone.mp4" ); audioPlayer.play("vlc" , "far far away.vlc" ); audioPlayer.play("avi" , "mind me.avi" ); } }
桥接模式 桥接模式( Bridge Pattern) 是用于把抽象化与实现化解耦, 使得二者可以独立变化。 这种类型的设计模式属于结构型模式, 它通过提供抽象化和实现化之间的桥接结构, 来实现二者的解耦。
这种模式涉及到一个作为桥接的接口, 使得实体类的功能独立于接口实现类。 这两种类型的类可被结构化改变而互不影响。
适用于双重维度的情况, 就是多对多的概念, 桥接类似于关联关系表的概念。
多种操作系统需要播放多种视频格式的文件
多种图形需要填充多种颜色
结构
实现化角色( 接口/抽象类)
具体的实现化角色( 实现类) 实现实现化角色中的方法
抽象化角色( 抽象类) 聚合实现化角色
扩展抽象化角色, 实现抽象化角色中的方法
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 public interface VideoFile { public void decode (String fileName) ; } public class AviVideoFile implements VideoFile { @Override public void decode (String fileName) { System.out.println("播放avi格式: " + fileName); } } public class Mp4VideoFile implements VideoFile { @Override public void decode (String fileName) { System.out.println("播放mp4格式: " + fileName); } } public class WmVideoFile implements VideoFile { @Override public void decode (String fileName) { System.out.println("播放wmv格式: " + fileName); } } public abstract class OperationSystem { protected VideoFile videoFile; public OperationSystem (VideoFile videoFile) { this .videoFile = videoFile; } public abstract void play (String fileName) ; } public class Mac extends OperationSystem { public Mac (VideoFile videoFile) { super (videoFile); } @Override public void play (String fileName) { videoFile.decode(fileName); } } public class Window extends OperationSystem { public Window (VideoFile videoFile) { super (videoFile); } @Override public void play (String fileName) { videoFile.decode(fileName); } } public class Client { public static void main (String[] args) { Window window = new Window (new Mp4VideoFile ()); window.play("岁月神偷" ); Window window1 = new Window (new WmVideoFile ()); window1.play("神话" ); Mac mac = new Mac (new AviVideoFile ()); mac.play("惜往事" ); } }
装饰者模式 装饰器模式( Decorator Pattern) 允许向一个现有的对象添加新的功能, 同时又不改变其结构。 这种类型的设计模式属于结构型模式, 它是作为现有的类的一个包装。
这种模式创建了一个装饰类, 用来包装原有的类, 并在保持类方法签名完整性的前提下, 提供了额外的功能。
结构
抽象构件角色: 定义一个抽象接口用以规范->准备接收附加责任的对象
具体构件角色: 实现抽象构件, 通过装饰角色为其添加一些职责
抽象装饰角色: 继承或实现抽象构件, 并包含具体构件角色的实例, 可以通过其子类扩展具体构建角色的功能
具体装饰角色: 实现抽象装饰的相关放啊, 并给具体构件对象添加附加的责任
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 public abstract class FastFood { private String name; private float price; public abstract float cost () ; public FastFood (String name, float price) { this .name = name; this .price = price; } public String getName () { return name; } public void setName (String name) { this .name = name; } public float getPrice () { return price; } public void setPrice (float price) { this .price = price; } } public class BanMian extends FastFood { public BanMian () { super ("板面" , 15f ); } @Override public float cost () { return getPrice(); } } public class MiXian extends FastFood { public MiXian () { super ("米线" , 16f ); } @Override public float cost () { return getPrice(); } } public abstract class Garnish extends FastFood { private FastFood fastFood; public void setFastFood (FastFood fastFood) { this .fastFood = fastFood; } public FastFood getFastFood () { return fastFood; } public Garnish (FastFood fastFood, String name, float price) { super (name, price); this .fastFood = fastFood; } } public class Egg extends Garnish { public Egg (FastFood fastFood) { super (fastFood, "鸡蛋" , 2f ); } @Override public float cost () { return getPrice() + getFastFood().cost(); } @Override public String getName () { return getFastFood().getName() + super .getName(); } } public class WanZi extends Garnish { public WanZi (FastFood fastFood) { super (fastFood, "丸子" , 3f ); } @Override public float cost () { return getPrice() + getFastFood().cost(); } @Override public String getName () { return getFastFood().getName() + super .getName(); } } public class Client { public static void main (String[] args) { FastFood foot = new BanMian (); foot = new Egg (foot); foot = new WanZi (foot); System.out.println(foot.getName()); System.out.println(foot.cost() + "元" ); } }
代理模式 在代理模式( Proxy Pattern) 中, 一个类代表另一个类的功能。 这种类型的设计模式属于结构型模式。
代理模式分为: 静态代理、 动态代理( JDK代理, cglib代理) 、 防火墙代理、 缓存代理、 远程代理、 同步代理
结构
静态代理 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 interface SellTickets { void sell () ; } public class TrainStation implements SellTickets { @Override public void sell () { System.out.println("火车站卖票" ); } } public class ProxyPoint implements SellTickets { private TrainStation trainStation = new TrainStation (); @Override public void sell () { System.out.println("代售点收取一些代理费用" ); trainStation.sell(); } } public class Client { public static void main (String[] args) { ProxyPoint proxyPoint = new ProxyPoint (); proxyPoint.sell(); } }
JDK代理 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 public interface SellTickets { void sell () ; } public class TrainStation implements SellTickets { @Override public void sell () { System.out.println("火车站卖票" ); } } public class ProxyFactory { public Object proxyObj; public ProxyFactory (Object proxyObj) { this .proxyObj = proxyObj; } public Object getProxyObject () { return Proxy.newProxyInstance( proxyObj.getClass().getClassLoader(), proxyObj.getClass().getInterfaces(), new InvocationHandler () { @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { System.out.println("使用JDK_Proxy动态代理" ); return method.invoke(proxyObj, args); } }); } } public class Client { public static void main (String[] args) { ProxyFactory proxyFactory = new ProxyFactory (new TrainStation ()); SellTickets proxyObject = (SellTickets) proxyFactory.getProxyObject(); proxyObject.sell(); } }
cglib代理 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 public class TrainStation { public void sell () { System.out.println("火车站卖票" ); } } public class ProxyFactory implements MethodInterceptor { public Object proxyObj; public ProxyFactory (Object proxyObj) { this .proxyObj = proxyObj; } public Object getProxyObject () { Enhancer enhancer = new Enhancer (); enhancer.setSuperclass(proxyObj.getClass()); enhancer.setCallback(this ); return enhancer.create(); } @Override public Object intercept (Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("使用cglib动态代理" ); return method.invoke(proxyObj, objects); } } public class Client { public static void main (String[] args) { ProxyFactory proxyFactory = new ProxyFactory (new TrainStation ()); TrainStation proxyObject = (TrainStation) proxyFactory.getProxyObject(); proxyObject.sell(); } }
外观模式 外观模式( Facade Pattern) 隐藏系统的复杂性, 并向客户端提供了一个客户端可以访问系统的接口。 这种类型的设计模式属于结构型模式, 它向现有的系统添加一个接口, 来隐藏系统的复杂性。
这种模式涉及到一个单一的类, 该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。
结构
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 public class AirCondition { public void on () { System.out.println("打开空调..." ); } public void off () { System.out.println("关闭空调..." ); } } public class Light { public void on () { System.out.println("打开电灯..." ); } public void off () { System.out.println("关闭电灯..." ); } } public class TV { public void on () { System.out.println("打开电视..." ); } public void off () { System.out.println("关闭电视..." ); } } public class Facade { private Light light; private TV tv; private AirCondition airCondition; public Facade () { this .light = new Light (); this .tv = new TV (); this .airCondition = new AirCondition (); } public void say (String str) { if (str.contains("打开" )) { on(); } else if (str.contains("关闭" )) { off(); } else { System.out.println("暂时还没有这个功能..." ); } } private void on () { light.on(); tv.on(); airCondition.on(); } private void off () { light.off(); tv.off(); airCondition.off(); } } public class Client { public static void main (String[] args) { Facade facade = new Facade (); facade.say("打开家电" ); facade.say("关闭家电" ); } }
享元模式 享元模式( Flyweight Pattern) 主要用于减少创建对象的数量, 以减少内存占用和提高性能。 这种类型的设计模式属于结构型模式, 它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式尝试重用现有的同类对象, 如果未找到匹配的对象, 则创建新对象。
结构
抽象享元角色: 通常是一个接口或抽象类, 在抽象享元类中声明了具体享元类公共的方法, 这些方法可以向外界提供享元对象的内部数据( 内部状态) , 同时也可以通过这些方法来设置外部数据( 外部状态)
具体享元角色: 它实现了抽象享元类, 称为享元对象; 在具体享元类中为内部状态提供了储存空间, 通常我们可以结合单例模式来设计具体享元类, 为每一个具体享元类提供唯一的享元对象。
非享元角色: 并不是所有的抽象享元类的子类都需要被共享, 不能被共享的子类可设计为非共享具体享元类; 当需要一个非共享具体享元类的对象时可以直接通过实例化创建。
享元工厂: 负责创建和管理享元角色。 当客户对象请求一个享元对象时, 享元工厂检查系统中是否存在符合要求的享元对象, 如果存在则提供给客户; 如果不存在的话, 则创建一个新的享元对象。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 public abstract class Box { public abstract String getShape () ; public void display (String color) { System.out.println("方块形状: " + getShape() + ", 颜色: " + color); } } public class IBox extends Box { @Override public String getShape () { return "I" ; } } public class LBox extends Box { @Override public String getShape () { return "L" ; } } public class OBox extends Box { @Override public String getShape () { return "O" ; } } public class BoxFactory { private HashMap<String, Box> map; private BoxFactory () { map = new HashMap <>(); map.put("I" , new IBox ()); map.put("L" , new LBox ()); map.put("O" , new OBox ()); } private static BoxFactory factory = new BoxFactory (); public static BoxFactory getInstance () { return factory; } public Box getShape (String name) { return map.get(name); } } public class Client { public static void main (String[] args) { BoxFactory instance = BoxFactory.getInstance(); Box i = instance.getShape("I" ); i.display("灰色" ); Box l = instance.getShape("L" ); l.display("绿色" ); Box o = instance.getShape("O" ); o.display("蓝色" ); Box o1 = instance.getShape("O" ); o1.display("紫色" ); System.out.println(o == o1); } }
组合模式 组合模式( Composite Pattern) , 又叫部分整体模式, 是用于把一组相似的对象当作一个单一的对象。 组合模式依据树形结构来组合对象, 用来表示部分以及整体层次。 这种类型的设计模式属于结构型模式, 它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。 该类提供了修改相同对象组的方式。
结构
抽象根节点: 定义系统各个层次的共有方法和属性, 可以先定义一些默认行为和属性。
树枝节点: 定义数值节点的行为, 储存子节点, 组合树枝节点和叶子节点形成一个树形结构。
叶子节点: 叶子节点对象, 其 下再无分支, 是系统层次遍历的最小单位。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 public abstract class MenuComponent { protected String name; protected int type; public void add (MenuComponent menuComponent) { throw new UnsupportedOperationException (); } public void remove (MenuComponent menuComponent) { throw new UnsupportedOperationException (); } public MenuComponent getChild (int index) { throw new UnsupportedOperationException (); } public String getName () { return name; } public abstract void print () ; } public class Menu extends MenuComponent { private List<MenuComponent> menuComponentList = new ArrayList <>(); public Menu (String name, int type) { this .name = name; this .type = type; } @Override public void add (MenuComponent menuComponent) { menuComponentList.add(menuComponent); } @Override public void remove (MenuComponent menuComponent) { menuComponentList.remove(menuComponent); } @Override public MenuComponent getChild (int index) { return menuComponentList.get(index); } @Override public void print () { String s = type == 1 ? ">" : "-" ; System.out.println(s + " " + name); menuComponentList.forEach(MenuComponent::print); } } public class MenuItem extends MenuComponent { public MenuItem (String name, int type) { this .name = name; this .type = type; } @Override public void print () { String s = type == 1 ? ">" : "-" ; System.out.println(s + " " + name); } } public class Client { public static void main (String[] args) { MenuComponent menu1 = new Menu ("菜单管理" , 1 ); menu1.add(new MenuItem ("页面访问" , 2 )); menu1.add(new MenuItem ("展开菜单" , 2 )); menu1.add(new MenuItem ("编辑菜单" , 2 )); menu1.add(new MenuItem ("删除菜单" , 2 )); menu1.add(new MenuItem ("新增菜单" , 2 )); MenuComponent menu2 = new Menu ("权限管理" , 1 ); menu2.add(new MenuItem ("页面访问" , 2 )); MenuItem menuItem = new MenuItem ("提交保存" , 2 ); menu2.add(menuItem); menu2.remove(menuItem); MenuComponent menu3 = new Menu ("角色管理" , 1 ); menu3.add(new MenuItem ("页面访问" , 2 )); menu3.add(new MenuItem ("新增角色" , 2 )); menu3.add(new MenuItem ("修改角色" , 2 )); menu3.add(new MenuItem ("删除角色" , 2 )); MenuComponent menuSys = new Menu ("系统管理" , 1 ); menuSys.add(menu1); menuSys.add(menu2); menuSys.add(menu3); MenuComponent menuEmploy = new Menu ("员工管理" , 1 ); MenuComponent company = new Menu ("公司管理平台" , 1 ); company.add(menuSys); company.add(menuEmploy); company.print(); MenuComponent child = company.getChild(0 ).getChild(1 ); child.print(); } }
行为型模式 这些设计模式特别关注对象之间的通信。
模板模式 在模板模式( Template Pattern) 中, 一个抽象类公开定义了执行它的方法的方式/模板。 它的子类可以按需要重写方法实现, 但调用将以抽象类中定义的方式进行。 这种类型的设计模式属于行为型模式。
结构
抽象类: 负责给出一个算法的轮廓和骨架, 它由一个模板方法和若干个基本方法构成
模板方法: 定义了算法的骨架, 按某种顺序调用其包含的方法
基本方法: 实现算法的各个步骤的方法, 是模板方法的组成部分, 基本方法可以分为三种
抽象方法: 一个抽象方法有抽象类声明、 由其具体子类实现
具体方法: 一个具体方法由一个抽象类或具体类声明实现, 其子类可以进行覆盖也可以直接继承
钩子方法: 在抽象类中已经实现, 包括用于判断的逻辑方法和需要子类重写的空方法两种, 一般钩子方法是用于判断的逻辑方法, 返回值类型为Boolean。
具体子类: 实现抽象类中定义所定义的抽象方法和钩子方法, 他们是一个顶级逻辑的组成步骤。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 public abstract class SoyaMilk { public final void make () { select(); if (isAddCondiments()) { addCondiments(); } soak(); beat(); } public void select () { System.out.println("选材料: 选择新鲜的黄豆" ); } public abstract void addCondiments () ; public void soak () { System.out.println("开始浸泡, 需要三个小时" ); } public void beat () { System.out.println("放入豆浆机开始制作豆浆" ); } public boolean isAddCondiments () { return true ; } } public class ChunSoyaMilk extends SoyaMilk { @Override public void addCondiments () { } @Override public boolean isAddCondiments () { return false ; } } public class HongdouSoyaMilk extends SoyaMilk { @Override public void addCondiments () { System.out.println("添加红豆配料" ); } } public class HongzaoSoyaMilk extends SoyaMilk { @Override public void addCondiments () { System.out.println("添加红枣配料" ); } } public class Client { public static void main (String[] args) { System.out.println("--- 制作红豆豆浆 ---" ); SoyaMilk hongdouSoyaMilk = new HongdouSoyaMilk (); hongdouSoyaMilk.make(); System.out.println("--- 制作红枣豆浆 ---" ); SoyaMilk hongzaoSoyaMilk = new HongzaoSoyaMilk (); hongzaoSoyaMilk.make(); System.out.println("--- 制作纯豆浆 ---" ); SoyaMilk chunSoyaMilk = new ChunSoyaMilk (); chunSoyaMilk.make(); } }
命令模式 命令模式( Command Pattern) 是一种数据驱动的设计模式, 它属于行为型模式。 请求以命令的形式包裹在对象中, 并传给调用对象。 调用对象寻找可以处理该命令的合适的对象, 并把该命令传给相应的对象, 该对象执行命令。
结构
抽象命令类角色: 定义命令接口, 声明执行的方法
具体命令角色: 具体的命令, 实现命令接口, 通常会持有接收者, 并调用接收者的功能来完成命令要执行的操作
实现者/接收者角色: 真正执行命令的对象, 任何类都可能成为一个接收者, 只要它能够实现命令要求实现的相应功能
调用者/请求者角色: 要求命令对象执行请求, 通常会持有命令对象, 可以持有很多的命令对象, 这个是客户端真正触发命令并要求命令执行相应操作的地方, 也就是说相当于使用命令对象的接口。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 public interface Command { public void execute () ; public void undo () ; } public class DengpaoOffCommand implements Command { Dengpao dengpao; public DengpaoOffCommand (Dengpao dengpao) { this .dengpao = dengpao; } @Override public void execute () { dengpao.off(); } @Override public void undo () { dengpao.on(); } } public class DengpaoOnCommand implements Command { Dengpao dengpao; public DengpaoOnCommand (Dengpao dengpao) { this .dengpao = dengpao; } @Override public void execute () { dengpao.on(); } @Override public void undo () { dengpao.off(); } } public class NoCommand implements Command { @Override public void execute () { } @Override public void undo () { } } public class Dengpao { public void on () { System.out.println("灯泡打开了..." ); } public void off () { System.out.println("灯泡关闭了..." ); } } public class RemoteController { Map<String, Command> onCommands; Map<String, Command> offCommands; Command undoCommand; public RemoteController () { onCommands = new HashMap <>(); offCommands = new HashMap <>(); } public void setCommand (String commandKey, Command onCommand, Command offCommand) { onCommands.put(commandKey, onCommand); offCommands.put(commandKey, offCommand); } public void onButtonPushed (String commandKey) { Command command = onCommands.get(commandKey); if (command != null ) { command.execute(); undoCommand = command; } } public void offButtonPushed (String commandKey) { Command command = offCommands.get(commandKey); if (command != null ) { command.execute(); undoCommand = command; } } public void undoButtonPushed () { if (undoCommand != null ) { undoCommand.undo(); } } } public class Client { public static void main (String[] args) { Dengpao dengpao = new Dengpao (); DengpaoOnCommand dengpaoOnCommand = new DengpaoOnCommand (dengpao); DengpaoOffCommand dengpaoOffCommand = new DengpaoOffCommand (dengpao); RemoteController remoteController = new RemoteController (); String dengpaoCommandKey = "dengpao" ; remoteController.setCommand(dengpaoCommandKey, dengpaoOnCommand, dengpaoOffCommand); remoteController.onButtonPushed(dengpaoCommandKey); remoteController.offButtonPushed(dengpaoCommandKey); remoteController.undoButtonPushed(); } }
策略模式 在策略模式( Strategy Pattern) 中, 一个类的行为或其算法可以在运行时更改。 这种类型的设计模式属于行为型模式。
该模式定义了一系列算法, 并将每个算法封装起来, 使它们可以相互替换, 且算法的变化不会影响使用算法的客户。
通过对算法进行封装, 把使用算法的责任和算法的实现分割开来, 并委派给不同的对象对这些算法进行管理。
结构
环境角色: 持有一个策略类的引用, 最终给客户端调用。
抽象策略角色: 通常由一个接口或者是抽象类实现, 此角色给出所有的具体策略类所需的接口。
具体策略角色: 实现了抽象策略定义的接口, 提供具体的算法实现或行为。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 public interface Strategy { void show () ; } public class StrategyA implements Strategy { @Override public void show () { System.out.println("买一送一" ); } } public class StrategyB implements Strategy { @Override public void show () { System.out.println("满二百减五十" ); } } public class StrategyC implements Strategy { @Override public void show () { System.out.println("满加一千元加一元换购任意二百元以下商品" ); } } public class SaleMan { private Strategy strategy; public SaleMan (Strategy strategy) { this .strategy = strategy; } public void setStrategy (Strategy strategy) { this .strategy = strategy; } public void show () { strategy.show(); } } public class Client { public static void main (String[] args) { SaleMan saleMan = new SaleMan (new StrategyA ()); saleMan.show(); saleMan.setStrategy(new StrategyB ()); saleMan.show(); saleMan.setStrategy(new StrategyC ()); saleMan.show(); } }
责任链模式 责任链模式( Chain of Responsibility Pattern) , 又叫职责链模式, 该模式为请求创建了一个接收者对象的链。 这种模式给予请求的类型, 对请求的发送者和接收者进行解耦。 这种类型的设计模式属于行为型模式。
在这种模式中, 通常每个接收者都包含对另一个接收者的引用。 如果一个对象不能处理该请求, 那么它会把相同的请求传给下一个接收者, 依此类推。
为了避免请求发送者与多个请求处理者耦合在一起, 将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链, 当有请求发生时, 可将请求沿着这条链传递, 直到有对象处理它为止。
结构
抽象处理者角色: 定义一个处理请求的接口, 包含抽象处理方法和一个后继连接。
具体处理者角色: 实现抽象处理者的处理方法, 判断是否可以处理本次请求, 如果可以处理请求则处理, 否则将该请求转给它的后继者。
客户类角色: 创建处理链, 并将链头的具体处理者对象提交请求, 它不关心处理细节和请求的传递过程。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 public abstract class Handler { protected final static int NUM_ONE = 1 ; protected final static int NUM_THREE = 3 ; protected final static int NUM_SEVEN = 7 ; private int numStart; private int numEnd; private Handler nextHandler; public Handler (int numStart) { this .numStart = numStart; } public Handler (int numStart, int numEnd) { this .numStart = numStart; this .numEnd = numEnd; } public void setNextHandler (Handler nextHandler) { this .nextHandler = nextHandler; } protected abstract void handlerLeave (LeaveRequest leave) ; public final void submit (LeaveRequest leave) { if (this .numStart <= leave.getNum() && leave.getNum() <= this .numEnd) { this .handlerLeave(leave); } else if (this .nextHandler != null ) { this .nextHandler.submit(leave); } else { System.out.println("请假天数不符合规定" ); } } } public class GeneralLeader extends Handler { public GeneralLeader () { super (NUM_THREE, NUM_SEVEN); } @Override protected void handlerLeave (LeaveRequest leave) { System.out.println(leave.getName() + "请假" + leave.getNum() + "天, " + leave.getContent()); System.out.println("总经理审批: 同意" ); } } public class ManagerLeader extends Handler { public ManagerLeader () { super (NUM_ONE, NUM_THREE); } @Override protected void handlerLeave (LeaveRequest leave) { System.out.println(leave.getName() + "请假" + leave.getNum() + "天, " + leave.getContent()); System.out.println("部门经理审批: 同意" ); } } public class GroupLeader extends Handler { public GroupLeader () { super (0 , NUM_ONE); } @Override protected void handlerLeave (LeaveRequest leave) { System.out.println(leave.getName() + "请假" + leave.getNum() + "天, " + leave.getContent()); System.out.println("小组长审批: 同意" ); } } public class LeaveRequest { private String name; private int num; private String content; public LeaveRequest (String name, int num, String content) { this .name = name; this .num = num; this .content = content; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getNum () { return num; } public void setNum (int num) { this .num = num; } public String getContent () { return content; } public void setContent (String content) { this .content = content; } } public class Client { public static void main (String[] args) { LeaveRequest request = new LeaveRequest ("小明" , 8 , "身体不适! " ); GroupLeader groupLeader = new GroupLeader (); ManagerLeader managerLeader = new ManagerLeader (); GeneralLeader generalLeader = new GeneralLeader (); groupLeader.setNextHandler(managerLeader); managerLeader.setNextHandler(generalLeader); groupLeader.submit(request); } }
状态模式 在状态模式( State Pattern) 中, 类的行为是基于它的状态改变的。 这种类型的设计模式属于行为型模式。
对有状态的对象, 把复杂的判断逻辑提取到不同的状态对象中, 允许状态对象在其内部状态发生改变时改变其行为。
结构
环境角色: 也称为上下文, 它定义了客户程序需要的接口, 维护一个当前状态, 并将于状态相关的操作委托给当前状态对象来处理。
抽象状态角色: 定义一个接口, 用于封装环境对象中的特定状态所对应的行为。
具体状态角色: 实现抽象状态所对应的行为。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 public class Context { public final static OpenState OPEN_STATE = new OpenState (); public final static CloseState CLOSE_STATE = new CloseState (); public final static RunState RUN_STATE = new RunState (); public final static StopState STOP_STATE = new StopState (); private LiftState liftState; public LiftState getLiftState () { return liftState; } public void setLiftState (LiftState liftState) { this .liftState = liftState; this .liftState.setContext(this ); } public void open () { this .liftState.open(); }; public void close () { this .liftState.close(); }; public void run () { this .liftState.run(); }; public void stop () { this .liftState.stop(); }; } public abstract class LiftState { protected Context context; public void setContext (Context context) { this .context = context; } public abstract void open () ; public abstract void close () ; public abstract void run () ; public abstract void stop () ; } public class CloseState extends LiftState { @Override public void open () { super .context.setLiftState(Context.OPEN_STATE); super .context.open(); } @Override public void close () { System.out.println("电梯关闭..." ); } @Override public void run () { super .context.setLiftState(Context.RUN_STATE); super .context.run(); } @Override public void stop () { super .context.setLiftState(Context.STOP_STATE); super .context.stop(); } } public class OpenState extends LiftState { @Override public void open () { System.out.println("电梯开启..." ); } @Override public void close () { super .context.setLiftState(Context.CLOSE_STATE); super .context.close(); } @Override public void run () { } @Override public void stop () { } } public class RunState extends LiftState { @Override public void open () { } @Override public void close () { } @Override public void run () { System.out.println("电梯正在运行..." ); } @Override public void stop () { super .context.setLiftState(Context.STOP_STATE); super .context.stop(); } } public class StopState extends LiftState { @Override public void open () { super .context.setLiftState(Context.OPEN_STATE); super .context.open(); } @Override public void close () { super .context.setLiftState(Context.CLOSE_STATE); super .context.close(); } @Override public void run () { super .context.setLiftState(Context.RUN_STATE); super .context.run(); } @Override public void stop () { System.out.println("电梯停止了..." ); } } public class Client { public static void main (String[] args) { Context context = new Context (); context.setLiftState(new RunState ()); context.open(); context.close(); context.run(); context.stop(); context.open(); } }
观察者模式 观察者模式( Observer Pattern) 又被称之为发布-订阅模式, 当一个对象被修改时, 则会自动通知依赖它的对象。 观察者模式属于行为型模式。
它定义了一种一对多的依赖关系, 让多个观察者对象同时监听某一个主题对象, 这个主题对象在状态发生变化时, 会通知所有观察者对象, 使他们能够自动更新。
JDK源码: java.util.Observable
结构
抽象主题( 抽象被观察者) : 抽象主题角色把所有观察者对象保存在一个集合里, 每个主题都可以有任意数量的观察者, 抽象主题提供一个接口, 可以增加和删除观察者对象。
具体主题( 具体被观察者) : 该角色将有关状态存入具体观察者对象, 在具体主题的内部状态发生改变时, 给所有注册过的观察者发送通知。
抽象观察者: 是观察者的抽象类, 它定义了一个更新接口, 使得在得到主题更改通知时更新自己。
具体观察者: 具体观察者, 实现抽象观察者定义的更新接口, 以便在得到主题更改通知时更新自己的状态。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 public interface Subject { public void add (Observer o) ; public void remove (Observer o) ; public void notify (String message) ; } public class SubscriptionSubject implements Subject { private ArrayList<Observer> observers = new ArrayList <>(); @Override public void add (Observer o) { observers.add(o); } @Override public void remove (Observer o) { observers.remove(o); } @Override public void notify (String message) { for (Observer observer : observers) { observer.update(message); } } } public interface Observer { public void update (String message) ; } public class WeXinUser implements Observer { private String name; public WeXinUser (String name) { this .name = name; } @Override public void update (String message) { System.out.println(name+"接到更新通知: " +message); } } public class Client { public static void main (String[] args) { SubscriptionSubject subscriptionSubject = new SubscriptionSubject (); subscriptionSubject.add(new WeXinUser ("孙悟空" )); subscriptionSubject.add(new WeXinUser ("猪悟能" )); subscriptionSubject.add(new WeXinUser ("沙悟净" )); subscriptionSubject.notify("师傅被妖怪抓走了。 。 。 " ); } }
中介者模式 中介者模式( Mediator Pattern) , 又叫调停模式, 是用来降低多个对象和类之间的通信复杂性。 这种模式提供了一个中介类, 该类通常处理不同类之间的通信, 并支持松耦合, 使代码易于维护。 中介者模式属于行为型模式。
定义一个中介角色来封装一系列对象之间的交互, 使原有对象之间的耦合松散, 且可以独立地改变它们之间的交互。
结构
抽象中介者角色: 它是中介者的接口, 提供了同事对象注册与转发同事对象信息的抽象方法。
具体中介者角色: 实现中介者接口, 定义一个List来管理同事对象, 协调各个同事角色之间的交互关系, 因此它依赖于同事角色。
抽象同事类角色: 定义同事类接口, 保存中介者对象, 提供同事对象交互的抽象方法, 实现所有相互影响的同事类的公共功能。
具体同事类角色: 是抽象同事类的实现者, 当需要与其他同事对象交互时, 由中介者对象负责后续的交互。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 public abstract class Mediator { public abstract void contact (String message, Person person) ; } public class MediatorStructure extends Mediator { private HouseOwner houseOwner; private Tenant tenant; @Override public void contact (String message, Person person) { if (person == houseOwner) { tenant.getMessage(message); } else { houseOwner.getMessage(message); } } public HouseOwner getHouseOwner () { return houseOwner; } public void setHouseOwner (HouseOwner houseOwner) { this .houseOwner = houseOwner; } public Tenant getTenant () { return tenant; } public void setTenant (Tenant tenant) { this .tenant = tenant; } } public abstract class Person { protected String name; protected Mediator mediator; public Person (String name, Mediator mediator) { this .name = name; this .mediator = mediator; } } public class HouseOwner extends Person { public HouseOwner (String name, Mediator mediator) { super (name, mediator); } public void contact (String message) { mediator.contact(message, this ); } public void getMessage (String message) { System.out.println("房主" + name + "获取到的信息是: " + message); } } public class Tenant extends Person { public Tenant (String name, Mediator mediator) { super (name, mediator); } public void contact (String message) { mediator.contact(message, this ); } public void getMessage (String message) { System.out.println("租房者" + name + "获取到的信息是: " + message); } } public class Client { public static void main (String[] args) { MediatorStructure mediatorStructure = new MediatorStructure (); Tenant tenant = new Tenant ("李四" , mediatorStructure); HouseOwner houseOwner = new HouseOwner ("张三" , mediatorStructure); mediatorStructure.setTenant(tenant); mediatorStructure.setHouseOwner(houseOwner); tenant.contact("我要租三室的房子! " ); houseOwner.contact("我这里有三室的房子你要租吗? " ); } }
迭代器模式 迭代器模式( Iterator Pattern) 是 Java 和 .Net 编程环境中非常常用的设计模式。 这种模式用于顺序访问集合对象的元素, 不需要知道集合对象的底层表示。 迭代器模式属于行为型模式。
提供一个对象来顺序访问聚合对象中的一系列数据, 而不暴露聚合对象的内部表示。
结构
抽象聚合角色: 定义储存、 添加、 删除聚合元素以及创建迭代器对象的接口
具体聚合角色: 实现抽象聚合类, 返回一个具体迭代器的实例。
抽象迭代器角色: 定义访问和遍历聚合元素的接口, 通常包含hasNext()、 next()等方法。
具体迭代器角色: 实现抽象迭代器接口中所定义的方法, 完成对聚合对象的遍历, 记录遍历的当前位置。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 public class Student { private String name; private String number; public Student (String name, String number) { this .name = name; this .number = number; } @Override public String toString () { return "Student{" + "name='" + name + '\'' + ", number='" + number + '\'' + '}' ; } public String getName () { return name; } public void setName (String name) { this .name = name; } public String getNumber () { return number; } public void setNumber (String number) { this .number = number; } } public interface StudentAggregate { void addStudent (Student student) ; void removeStudent (Student student) ; StudentIterator getStudentIterator () ; } public class StudentAggregateImpl implements StudentAggregate { private List<Student> list = new ArrayList <>(); @Override public void addStudent (Student student) { list.add(student); } @Override public void removeStudent (Student student) { list.remove(student); } @Override public StudentIterator getStudentIterator () { return new StudentIteratorImpl (list); } } public interface StudentIterator { boolean hasNext () ; Student next () ; } public class StudentIteratorImpl implements StudentIterator { private List<Student> list; private int position = 0 ; public StudentIteratorImpl (List<Student> list) { this .list = list; } @Override public boolean hasNext () { return position < list.size(); } @Override public Student next () { Student student = list.get(position); position++; return student; } } public class Client { public static void main (String[] args) { StudentAggregateImpl aggregate = new StudentAggregateImpl (); aggregate.addStudent(new Student ("张三" , "001" )); aggregate.addStudent(new Student ("李四" , "002" )); aggregate.addStudent(new Student ("王五" , "003" )); aggregate.addStudent(new Student ("赵六" , "004" )); StudentIterator iterator = aggregate.getStudentIterator(); while (iterator.hasNext()){ Student next = iterator.next(); System.out.println(next.toString()); } } }
访问者模式 在访问者模式( Visitor Pattern) 中, 我们使用了一个访问者类, 它改变了元素类的执行算法。 通过这种方式, 元素的执行算法可以随着访问者改变而改变。 这种类型的设计模式属于行为型模式。 根据模式, 元素对象已接受访问者对象, 这样访问者对象就可以处理元素对象上的操作。
封装一些作用于某种数据结构中的各元素的操作, 它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
结构
抽象访问者角色: 定义了对每一个元素访问的行为, 它的参数就是可以访问的元素, 它的方法个数理论上来讲与元素类个数是一样的, 访问者模式要求元素类的个数不能改变。
具体访问者角色: 给出对每一个元素类访问时所产生的具体行为。
抽象元素角色: 定义了一个接受访问者的方法, 其意义是指, 每一个元素都要可以被访问者访问。
具体元素角色: 提供接受访问方法的具体实现, 而这个具体的实现, 通常情况下是使用访问者提供的访问该元素类的方法。
对象结构角色: 定义当中所提到的对象结构, 对象结构是一个抽象表述, 具体点可以理解为一个具有容器性质或者复合对象特性的类, 它会含有一组元素, 并且可以迭代这些元素, 供访问者访问。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 public interface Person { void feed (Cat cat) ; void feed (Dog cat) ; } public class Owner implements Person { @Override public void feed (Cat cat) { System.out.println("主人给猫咪喂食..." ); } @Override public void feed (Dog cat) { System.out.println("主人给狗狗喂食..." ); } } public class Someone implements Person { @Override public void feed (Cat cat) { System.out.println("其他人给猫咪喂食..." ); } @Override public void feed (Dog cat) { System.out.println("其他人给狗狗喂食..." ); } } public interface Animal { void accept (Person person) ; } public class Cat implements Animal { @Override public void accept (Person person) { person.feed(this ); System.out.println("喵喵喵..." ); } } public class Dog implements Animal { @Override public void accept (Person person) { person.feed(this ); System.out.println("汪汪汪..." ); } } public class Home { private List<Animal> animals = new ArrayList <>(); public void add (Animal animal) { animals.add(animal); } public void action (Person person) { for (Animal animal:animals) { animal.accept(person); } } } public class Client { public static void main (String[] args) { Home home = new Home (); home.add(new Cat ()); home.add(new Dog ()); Owner owner = new Owner (); home.action(owner); } }
备忘录模式 备忘录模式( Memento Pattern) , 又叫快照模式, 在不破坏封装性的前提下, 捕获一个对象的内部状态, 并在该对象之外保存这个状态, 以便以后当需要时能将该对象恢复到原先保存的状态。 备忘录模式属于行为型模式。
结构
发起人角色: 记录当前时刻的内部状态信息, 提供创建备忘录和恢复备忘录数据的功能, 实现其他业务功能, 它可以访问备忘录里的所有信息。
备忘录角色: 负责存储发起人的内部状态, 在需要的时候提供这些内部状态给发起人。
管理者角色: 对备忘录进行管理, 提供保存与获取备忘录功能, 但其不能对备忘录的内容进行访问与修改。
备忘录有两个等效的接口
窄接口: 管理者对象( 和其他发起人对象之外的任何对象) 看到的都是备忘录的窄接口, 这个窄接口只允许它把备忘录对象传给其他对象。
宽接口: 与管理者看到的窄接口相反, 发起人对象可以看到一个宽接口, 这个宽接口允许它读取所有的数据, 以便根据这些数据恢复这个发起人对象的内部状态。
例一 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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 public interface Memento {} public class GameRole { private int vit; private int atk; private int def; private class RoleStateMemento implements Memento { private int vit; private int atk; private int def; public RoleStateMemento (int vit, int atk, int def) { this .vit = vit; this .atk = atk; this .def = def; } public int getVit () { return vit; } public int getAtk () { return atk; } public int getDef () { return def; } } public void initState () { this .vit = 100 ; this .atk = 100 ; this .def = 100 ; } public void fight () { this .vit = 0 ; this .atk = 0 ; this .def = 0 ; } public Memento savaState () { return new RoleStateMemento (this .vit, this .atk, this .def); } public void recoverState (Memento memento) { RoleStateMemento roleStateMemento = (RoleStateMemento) memento; this .vit = roleStateMemento.getVit(); this .atk = roleStateMemento.getAtk(); this .def = roleStateMemento.getDef(); } public void stateDisplay () { System.out.println("======角色面板======" ); System.out.println("角色生命力: " +this .vit); System.out.println("角色攻击力: " +this .atk); System.out.println("角色防御力: " +this .def); System.out.println("===================" ); } } public class RoleStateCaretaker { private Memento memento; public Memento getMemento () { return memento; } public void setMemento (Memento memento) { this .memento = memento; } } public class Client { public static void main (String[] args) { System.out.println("初始化角色" ); GameRole gameRole = new GameRole (); gameRole.initState(); gameRole.stateDisplay(); RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker (); Memento roleStateMemento = gameRole.savaState(); roleStateCaretaker.setMemento(roleStateMemento); System.out.println("角色死亡" ); gameRole.fight(); gameRole.stateDisplay(); System.out.println("回档" ); gameRole.recoverState(roleStateCaretaker.getMemento()); gameRole.stateDisplay(); } }
例二 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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 public class GameRole { private int vit; private int atk; private int def; public void initState () { this .vit = 100 ; this .atk = 100 ; this .def = 100 ; } public void fight () { this .vit = 0 ; this .atk = 0 ; this .def = 0 ; } public RoleStateMemento savaState () { return new RoleStateMemento (this .vit, this .atk, this .def); } public void recoverState (RoleStateMemento roleStateMemento) { this .vit = roleStateMemento.getVit(); this .atk = roleStateMemento.getAtk(); this .def = roleStateMemento.getDef(); } public void stateDisplay () { System.out.println("======角色面板======" ); System.out.println("角色生命力: " +this .vit); System.out.println("角色攻击力: " +this .atk); System.out.println("角色防御力: " +this .def); System.out.println("===================" ); } } public class RoleStateMemento { private int vit; private int atk; private int def; public RoleStateMemento (int vit, int atk, int def) { this .vit = vit; this .atk = atk; this .def = def; } public int getVit () { return vit; } public void setVit (int vit) { this .vit = vit; } public int getAtk () { return atk; } public void setAtk (int atk) { this .atk = atk; } public int getDef () { return def; } public void setDef (int def) { this .def = def; } } public class RoleStateCaretaker { private RoleStateMemento roleStateMemento; public RoleStateMemento getRoleStateMemento () { return roleStateMemento; } public void setRoleStateMemento (RoleStateMemento roleStateMemento) { this .roleStateMemento = roleStateMemento; } } public class Client { public static void main (String[] args) { System.out.println("初始化角色" ); GameRole gameRole = new GameRole (); gameRole.initState(); gameRole.stateDisplay(); RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker (); RoleStateMemento roleStateMemento = gameRole.savaState(); roleStateCaretaker.setRoleStateMemento(roleStateMemento); System.out.println("角色死亡" ); gameRole.fight(); gameRole.stateDisplay(); System.out.println("回档" ); gameRole.recoverState(roleStateCaretaker.getRoleStateMemento()); gameRole.stateDisplay(); } }
解释器模式 解释器模式( Interpreter Pattern) 提供了评估语言的语法或表达式的方式, 它属于行为型模式。 这种模式实现了一个表达式接口, 该接口解释一个特定的上下文。 这种模式被用在 SQL 解析、 符号处理引擎等。
给定一个语言, 定义它的文法表示, 并定义一个解释器, 这个解释器使用该标识来解释语言中的句子。
结构
抽象表达式角色: 定义解释器接口, 约定解释器的解释操作。
终结符表达式角色: 抽象表达式的子类, 用来实现文法中与终结符相关的操作, 文法中的每一个终结符都有一个具体终结表达式与之相对应。
非终结符表达式角色: 抽象表达式的子类, 用来实现文法中与非终结符相关的操作, 文法中的每条规则都对应一个非终结符表达式。
环境角色: 通常包含各个解释器需要的数据或是公共的功能, 一般用来传递被所有解释器共享的数据, 后面的解释器可以从这里获取这些值。
客户端: 主要任务是将需要分析的句子或者表达式转换成使用解释器对象描述的抽象语法树, 然后调用解释器的解释方法, 也可以通过环境角色间接访问解释器的解释方法。
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 public abstract class AbstractExpression { public abstract int interpret (Context context) ; } public class Variable extends AbstractExpression { private String name; public Variable (String name) { this .name = name; } @Override public int interpret (Context context) { return context.getValue(this ); } @Override public String toString () { return name; } } public class Minus extends AbstractExpression { private AbstractExpression left; private AbstractExpression right; public Minus (AbstractExpression left, AbstractExpression right) { this .left = left; this .right = right; } @Override public int interpret (Context context) { return this .left.interpret(context) - this .right.interpret(context); } @Override public String toString () { return "(" + this .left.toString() + " - " + this .right.toString() + ")" ; } } public class Plus extends AbstractExpression { private AbstractExpression left; private AbstractExpression right; public Plus (AbstractExpression left, AbstractExpression right) { this .left = left; this .right = right; } @Override public int interpret (Context context) { return this .left.interpret(context) + this .right.interpret(context); } @Override public String toString () { return "(" + this .left.toString() + " + " + this .right.toString() + ")" ; } } public class Context { private Map<Variable, Integer> map; public Context () { map = new HashMap <>(); } public void assign (Variable variable, Integer value) { map.put(variable, value); } public Integer getValue (Variable variable) { return map.get(variable); } } public class Client { public static void main (String[] args) { Context context = new Context (); Variable a = new Variable ("a" ); Variable b = new Variable ("b" ); Variable c = new Variable ("c" ); Variable d = new Variable ("d" ); context.assign(a, 1 ); context.assign(b, 2 ); context.assign(c, 3 ); context.assign(d, 4 ); AbstractExpression abstractExpression = new Plus (a, new Plus (new Minus (b, c), d)); int result = abstractExpression.interpret(context); System.out.println(abstractExpression + " = " + result); } }
学习资源
视频
书籍
《 图解设计模式》
《 Head First 设计模式》
《 大话设计模式》
《 设计模式: 可复用面向对象软件的基础》
文档