软件设计模式
软件设计模式
简介
软件工程中,设计模式(Design Pattern)是对软件设计中普遍存在的各种问题,所提出的解决方案。是从建筑设计领域引入计算机科学的。设计模式是为了让软件具有更好的代码重用性、可读性、可扩展性、可靠性。
UML图
UML简介
UML(Unified Modeling Language)是统一建模语言。是一种用于软件系统分析和设计的语言工具,它用于帮助软件开发人员进行思考和记录思路的结果。其本身是一套符号的规定,就像数学符号和化学符号一样。这些符号用于描述软件模型中的各个元素和他们之间的关系,比如类、接口、实现、泛化、依赖、组合、聚合等。UML建模工具常用有Rational Rose,也可以使用一些插件来建模。
UML分类
分为用例图、静态结构图、动态行为图。
用例图
静态结构图:类图、对象图、包图、组件图、部署图
动态行为图:交互图、状态图、活动图
UML类图
用于描述系统中类本身的组成和类之间的各种静态关系。
类之间的关系:依赖、泛化、实现、关联、聚合、组合
依赖:只要是在类中用到了对方,则就存在依赖关系。使用方指向依赖方。
泛化:泛化实际就是继承,是依赖关系的一种。子类指向父类
实现:实现接口就是实现关系,是依赖关系的一种。由实现方指向接口方。
关联:类与类之间的联系,是依赖关系的一种。具有导航性,即双向关系或单向关系。A类用到了B类则由A指向B是单向关系。如果B类也用到了A类,则B类也要指向A类是双向关系。
聚合:表示整体和部分的关系,整体和部分可以分开,聚合关系是关联关系的特例。具有关联的导航性与多重性。A类使用到了B类,则空心菱形指向A类。
组合:表示整体和部分的关系,整体和部分不可以分开。比如A类使用了B类,A类消失B类也消失则说明其不能分开是组合关系。这种情况一般是A类中有一个B类的属性,并且直接new出来了一个B类对象。实心菱形指向A类。

类图画法
package com.tensoflow;
public class Person {
private Integer id;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

七大原则
设计模式原则,是程序员在编程时应当遵守的原则。也是各种设计模式的基础,是设计模式为什么这样设计的依据。
单一职责原则
对类来说一个类应该只负责一项职责。如果A类负责职责1、职责2两个不同的职责当职责1需求变更而改变A时,可能造成职责2执行错误。此时应将A类分成两份分别负责职责1和职责2。
package com.tensoflow.principle.singleResponsibility.problem;
class Vehicle {
public void run(String vehicle) {
System.out.println(vehicle + " 在公路上运行...");
}
}
/*
Vehicle交通工具类: run()方法违反了单一职责原则
解决方案: 应该根据交通工具运行方法不同,分解成不同的类
*/
public class SingleResponsibility {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.run("摩托车");
vehicle.run("汽车");
// 飞机不能在公路上运行
vehicle.run("飞机");
}
}
package com.tensoflow.principle.singleResponsibility.improve0;
class RoadVehicle {
public void run(String vehicle) {
System.out.println(vehicle + " 在公路上运行...");
}
}
class AirVehicle {
public void run(String vehicle) {
System.out.println(vehicle + " 在天空上运行...");
}
}
class WaterVehicle {
public void run(String vehicle) {
System.out.println(vehicle + " 在水上运行...");
}
}
/*
此种方式遵循了单一职责原则
弊端: 这种方式的改动很大,要将类分解,同时要修改客户端
改进: 直接修改Vehicle类,改动的代码会比较少
*/
public class SingleResponsibility {
public static void main(String[] args) {
RoadVehicle roadVehicle = new RoadVehicle();
roadVehicle.run("摩托车");
AirVehicle airVehicle = new AirVehicle();
airVehicle.run("飞机");
WaterVehicle waterVehicle = new WaterVehicle();
waterVehicle.run("轮船");
}
}
package com.tensoflow.principle.singleResponsibility.improve1;
class Vehicle {
public void runRoad(String vehicle) {
System.out.println(vehicle + " 在公路上运行...");
}
public void runAir(String vehicle) {
System.out.println(vehicle + " 在天空上运行...");
}
public void runWater(String vehicle) {
System.out.println(vehicle + " 在水上运行...");
}
}
/*
此方式没有对原本类做大的修改,只是增加方法
此方式虽然没有在类上遵守单一职责原则,但是在方法级别上仍遵守单一职责原则
*/
public class SingleResponsibility {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.runRoad("摩托车");
vehicle.runAir("飞机");
vehicle.runWater("轮船");
}
}
通常情况下,我们应当遵守单一职责原则。只有逻辑足够简单时才可以在代码级别违反单一职责原则。只有类中方法数量足够少时才可以在方法级别上保持单一职责原则。
迪米特法则
一个对象应该对其它对象保持最少的了解。类与类关系越密切,耦合度越大。迪米特法则又叫最少知道原则。即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public方法,不对外泄露任何信息。
package com.tensoflow.principle.demeter.problem;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
// 学校总部员工类
@Data
class Employee {
private String id;
}
// 学院员工类
@Data
class CollegeEmployee {
private String id;
}
// 管理学院员工的管理类
class CollegeManagement {
public List<CollegeEmployee> getAllEmployee() {
List<CollegeEmployee> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
CollegeEmployee emp = new CollegeEmployee();
emp.setId("学院员工Id = " + i);
list.add(emp);
}
return list;
}
}
/*
管理学校总部员工的管理类
SchoolManagement的直接朋友:Employee、CollegeManagement
SchoolManagement的间接朋友:CollegeEmployee 这样违背了迪米特法则
*/
class SchoolManagement {
public List<Employee> getAllEmployee() {
List<Employee> list = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setId("学校总部员工Id = " + i);
list.add(emp);
}
return list;
}
// 输出学校总部和学院员工信息的方法
void printAllEmployee(CollegeManagement sub) {
// 输出学院员工信息的代码不应该写在学校管理类中,应写到管理学院的类中
List<CollegeEmployee> list1 = sub.getAllEmployee();
System.out.println("--------------分公司员工--------------");
for(CollegeEmployee e : list1) {
System.out.println(e.getId());
}
List<Employee> list2 = this.getAllEmployee();
System.out.println("--------------学校总部员工--------------");
for(Employee e : list2) {
System.out.println(e.getId());
}
}
}
public class demeter {
public static void main(String[] args) {
SchoolManagement schoolManagement = new SchoolManagement();
schoolManagement.printAllEmployee(new CollegeManagement());
}
}
package com.tensoflow.principle.demeter.improve1;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
// 学校总部员工类
@Data
class Employee {
private String id;
}
// 学院员工类
@Data
class CollegeEmployee {
private String id;
}
// 管理学院员工的管理类
class CollegeManagement {
public List<CollegeEmployee> getAllEmployee() {
List<CollegeEmployee> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
CollegeEmployee emp = new CollegeEmployee();
emp.setId("学院员工Id = " + i);
list.add(emp);
}
return list;
}
public void printEmployee() {
List<CollegeEmployee> list = this.getAllEmployee();
System.out.println("--------------分公司员工--------------");
for(CollegeEmployee e : list) {
System.out.println(e.getId());
}
}
}
class SchoolManagement {
public List<Employee> getAllEmployee() {
List<Employee> list = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setId("学校总部员工Id = " + i);
list.add(emp);
}
return list;
}
// 输出学校总部和学院员工信息的方法
void printAllEmployee(CollegeManagement sub) {
// 将输出学院员工方法封装到CollegeManagement中去
sub.printEmployee();
List<Employee> list = this.getAllEmployee();
System.out.println("--------------学校总部员工--------------");
for(Employee e : list) {
System.out.println(e.getId());
}
}
}
public class demeter {
public static void main(String[] args) {
SchoolManagement schoolManagement = new SchoolManagement();
schoolManagement.printAllEmployee(new CollegeManagement());
}
}
接口隔离原则
客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。
package com.tensoflow.principle.segregation.problem;
interface Interface1 {
void operation1();
void operation2();
void operation3();
void operation4();
void operation5();
}
class B implements Interface1 {
@Override
public void operation1() {
System.out.println("B 实现了 operation1");
}
@Override
public void operation2() {
System.out.println("B 实现了 operation2");
}
@Override
public void operation3() {
System.out.println("B 实现了 operation3");
}
@Override
public void operation4() {
System.out.println("B 实现了 operation4");
}
@Override
public void operation5() {
System.out.println("B 实现了 operation5");
}
}
class D implements Interface1 {
@Override
public void operation1() {
System.out.println("D 实现了 operation1");
}
@Override
public void operation2() {
System.out.println("D 实现了 operation2");
}
@Override
public void operation3() {
System.out.println("D 实现了 operation3");
}
@Override
public void operation4() {
System.out.println("D 实现了 operation4");
}
@Override
public void operation5() {
System.out.println("D 实现了 operation5");
}
}
// A类通过Interface1接口依赖(使用)B类,只会用到1,2,3个方法
class A {
public void depend1(Interface1 i) {
i.operation1();
}
public void depend2(Interface1 i) {
i.operation2();
}
public void depend3(Interface1 i) {
i.operation3();
}
}
// C类通过Interface1接口依赖(使用)D类,只会用到1,4,5个方法
class C {
public void depend1(Interface1 i) {
i.operation1();
}
public void depend4(Interface1 i) {
i.operation4();
}
public void depend5(Interface1 i) {
i.operation5();
}
}
/*
问题分析:
B类实现了Interface1接口
A类通过Interface1接口依赖B类
但是接口对于A类来说不是最小接口,因为A类只会使用接口中的1,2,3方法
B类需要实现接口的所有方法。造成了B类实现了根本不需要实现的方法
解决方式:
将接口Interface1拆分为独立的几个接口,A类和C类分别与它们需要的接口建立依赖关系
*/
public class Segregation {
public static void main(String[] args) {
A a = new A();
a.depend1(new B());
a.depend2(new B());
a.depend3(new B());
}
}
package com.tensoflow.principle.segregation.improve1;
interface Interface1 {
void operation1();
}
interface Interface2 {
void operation2();
void operation3();
}
interface Interface3 {
void operation4();
void operation5();
}
class B implements Interface1, Interface2 {
@Override
public void operation1() {
System.out.println("B 实现了 operation1");
}
@Override
public void operation2() {
System.out.println("B 实现了 operation2");
}
@Override
public void operation3() {
System.out.println("B 实现了 operation3");
}
}
class D implements Interface1, Interface3 {
@Override
public void operation1() {
System.out.println("D 实现了 operation1");
}
@Override
public void operation4() {
System.out.println("D 实现了 operation4");
}
@Override
public void operation5() {
System.out.println("D 实现了 operation5");
}
}
// A类通过Interface1、Interface2接口依赖(使用)B类,只会用到1,2,3个方法
class A {
public void depend1(Interface1 i) {
i.operation1();
}
public void depend2(Interface2 i) {
i.operation2();
}
public void depend3(Interface2 i) {
i.operation3();
}
}
// C类通过Interface1、Interface3接口依赖(使用)D类,只会用到1,4,5个方法
class C {
public void depend1(Interface1 i) {
i.operation1();
}
public void depend4(Interface3 i) {
i.operation4();
}
public void depend5(Interface3 i) {
i.operation5();
}
}
public class Segregation {
public static void main(String[] args) {
A a = new A();
a.depend1(new B());
a.depend2(new B());
a.depend3(new B());
C c = new C();
c.depend1(new D());
c.depend4(new D());
c.depend5(new D());
}
}
依赖倒转原则
高层模块不应该依赖底层模块,二者都应该依赖其抽象
抽象不应该依赖细节,细节应该依赖抽象
依赖倒转原则的中心思想:面向接口编程
依赖倒转原则的设计理念:相对于细节的多变性,抽象的东西要稳定的多,以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在Java中,抽象指的是接口或抽象类,细节就是具体的实现类。
使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。
package com.tensoflow.principle.inversion.problem;
class Email {
public String getInfo() {
return "电子邮件信息: Hello World!";
}
}
class Person {
public void receive(Email email) {
System.out.println(email.getInfo());
}
}
/*
Person有接收邮件消息的功能
问题分析:
如果需要获取的对象是微信、短信等。则需要增加新的类并且Person也要增加相应的接收方法
解决方案:
引入一个抽象的接口IReceiver,表示接收者让Person类与接口发生依赖。
然后让Email、WeiXin等去实现IReceiver接口。
*/
public class Inversion {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
}
}
package com.tensoflow.principle.inversion.improve1;
interface IReceive {
String getInfo();
}
class Email implements IReceive {
@Override
public String getInfo() {
return "电子邮件信息: Hello World!";
}
}
class WeiXin implements IReceive {
@Override
public String getInfo() {
return "微信信息: Hello TenSoFlow!";
}
}
// 依赖接口不要依赖具体类
class Person {
public void receive(IReceive iReceive) {
System.out.println(iReceive.getInfo());
}
}
public class Inversion {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
person.receive(new WeiXin());
}
}
里氏替换原则
在使用继承时,在子类中尽量不要重写父类的方法。在适当的情况下,可以通过聚合、组合、依赖的来解决问题。
package com.tensoflow.principle.liskov.problem;
class A {
// 两数求差
public int func1(int a, int b) {
return a - b;
}
}
// B类继承了A
// 并增加了一个新功能:完成两个数相加然后和9求和
class B extends A {
// B类重写了父类方法,改变了其逻辑
@Override
public int func1(int a, int b) {
return a + b;
}
// 新功能:完成两个数相加然后和9求和
public int func2(int a, int b) {
return func1(a, b) + 9;
}
}
/*
问题分析:
原来运行正常的求差功能发生了错误,原因是B类无语重写了父类方法,造成原有功能出现错误。
在实际编程中常常会重写父类方法完成新功能,这样写起来虽然简单,但是整个集成体系的复用性会比较差。
特别是运行多态比较频繁的时候。
解决方案:
原来的父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖、聚合、组合等关系代替。
*/
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println("11 - 3 = " + a.func1(11, 3));
System.out.println("-------------------");
B b = new B();
// 这里本意是求出11 - 3的结果但是B已经重写了A中的方法造成结果错误
System.out.println("11 - 3 = " + b.func1(11, 3));
System.out.println("11 + 3 + 9 = " + b.func2(11, 3));
}
}
package com.tensoflow.principle.liskov.improve1;
class Base {
// 把更加基础的方法和成员写到Base类
}
class A extends Base{
// 两数求差
public int func1(int a, int b) {
return a - b;
}
}
class B extends Base {
private A a = new A();
// 保持自己的func1逻辑
public int func1(int a, int b) {
return a + b;
}
// 新功能:完成两个数相加然后和9求和
public int func2(int a, int b) {
return func1(a, b) + 9;
}
// 在func3中使用A的方法
public int func3(int a, int b) {
return this.a.func1(a, b);
}
}
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println("11 - 3 = " + a.func1(11, 3));
System.out.println("-------------------");
B b = new B();
// B类不再继承A类,因此调用者不会再认为func1是减法了
System.out.println("11 + 3 = " + b.func1(11, 3));
System.out.println("11 + 3 + 9 = " + b.func2(11, 3));
System.out.println("11 - 3 = " + b.func3(11, 3));
}
}
合成复用原则
原则是尽量使用合成或聚合的方式,而不是使用继承。
开闭原则
模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。
package com.tensoflow.principle.openClose.problem;
// 绘图类 (使用方)
class GraphicEditor {
public void drawShape(Shape s) {
if (s.m_type == 1) {
drawRectangle(s);
} else if (s.m_type == 2) {
drawCircle(s);
}
}
private void drawRectangle(Shape r) {
System.out.println("矩形");
}
private void drawCircle(Shape r) {
System.out.println("圆形");
}
}
class Shape {
int m_type;
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
}
/*
问题分析:
违反了开闭原则,如果需要增加一个绘制三角形的方法需要更改绘图类(使用方)的代码
解决方案:
把Shape类做成抽象类,并提供一个抽象的draw方法,打子类去实现即可
*/
public class OpenClose {
public static void main(String[] args) {
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
}
}
package com.tensoflow.principle.openClose.improve1;
// 绘图类 (使用方)
class GraphicEditor {
public void drawShape(Shape s) {
s.draw();
}
}
abstract class Shape {
public abstract void draw();
}
class Rectangle extends Shape {
@Override
public void draw() {
System.out.println("矩形");
}
}
class Circle extends Shape {
@Override
public void draw() {
System.out.println("圆形");
}
}
class Triangle extends Shape {
@Override
public void draw() {
System.out.println("三角形");
}
}
public class OpenClose {
public static void main(String[] args) {
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
graphicEditor.drawShape(new Triangle());
}
}
创建型模式
单例模式
采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。JDK中Runtime类就是经典的单例模式。
饿汉式(静态变量) -- 可以使用
package com.tensoflow.designPattern.singleton.way01;
/**
* 饿汉式(静态变量)
*/
class MySingleton {
// 构造器私有化,外部不能通过new关键字创建实例
private MySingleton() {}
// 本地内部创建对象实例
private final static MySingleton instance = new MySingleton();
// 对外提供一个公有的静态方法,返回实例对象
public static MySingleton getInstance() {
return instance;
}
}
public class Singleton {
public static void main(String[] args) {
MySingleton instance = MySingleton.getInstance();
MySingleton instance1 = MySingleton.getInstance();
System.out.println(instance == instance1); // true
}
}
优点:写法简单,在类装载的时候就完成实例化。避免了线程同步问题是线程安全的。
缺点:在类装载的时候就完成实例化,没有达到懒加载的效果,如果从始至终从未使用过这个实例,则会造成内存浪费。
总结:这种单例模式可用,可能会造成内存浪费。
饿汉式(静态代码块) -- 不推荐使用
package com.tensoflow.designPattern.singleton.way02;
/**
* 饿汉式(静态代码块)
*/
class MySingleton {
// 构造器私有化,外部不能通过new关键字创建实例
private MySingleton() {}
// 定义私有属性
private static MySingleton instance;
// 静态代码块中创建对象实例
static {
instance = new MySingleton();
}
// 对外提供一个公有的静态方法,返回实例对象
public static MySingleton getInstance() {
return instance;
}
}
public class Singleton {
public static void main(String[] args) {
MySingleton instance = MySingleton.getInstance();
MySingleton instance1 = MySingleton.getInstance();
System.out.println(instance == instance1); // true
}
}
饿汉式(静态代码块)和饿汉式(静态变量)方式一样,只不过创建实例位置在静态代码块中。
懒汉式(线程不安全) -- 不推荐使用
package com.tensoflow.designPattern.singleton.way03;
/**
* 懒汉式(线程不安全)
*/
class MySingleton {
// 构造器私有化,外部不能通过new关键字创建实例
private MySingleton() {}
// 定义私有属性
private static MySingleton instance;
// 对外提供一个公有的静态方法,返回实例对象
public static MySingleton getInstance() {
if (null == instance) {
instance = new MySingleton();
}
return instance;
}
}
public class Singleton {
public static void main(String[] args) {
MySingleton instance = MySingleton.getInstance();
MySingleton instance1 = MySingleton.getInstance();
System.out.println(instance == instance1); // true
}
}
起到了懒加载的效果,但是只能在单线程下使用。
懒汉式(线程安全-效率低) -- 不推荐使用
package com.tensoflow.designPattern.singleton.way04;
/**
* 懒汉式(线程安全-效率低)
*/
class MySingleton {
// 构造器私有化,外部不能通过new关键字创建实例
private MySingleton() {}
// 定义私有属性
private static MySingleton instance;
// 对外提供一个公有的静态方法,加入synchronized,返回实例对象
public static synchronized MySingleton getInstance() {
if (null == instance) {
instance = new MySingleton();
}
return instance;
}
}
public class Singleton {
public static void main(String[] args) {
MySingleton instance = MySingleton.getInstance();
MySingleton instance1 = MySingleton.getInstance();
System.out.println(instance == instance1); // true
}
}
达到了懒加载的效果,也达到了线程安全,但是效率低。
懒汉式(线程安全-效率高) -- 推荐使用
package com.tensoflow.designPattern.singleton.way05;
/**
* 懒汉式(线程安全-效率高)
*/
class MySingleton {
// 构造器私有化,外部不能通过new关键字创建实例
private MySingleton() {}
// 定义私有属性 volatile可以立即更新到主存
private static volatile MySingleton instance;
// 对外提供一个公有的静态方法,返回实例对象
public static MySingleton getInstance() {
if (null == instance) {
synchronized (MySingleton.class) {
if (null == instance) {
instance = new MySingleton();
}
}
}
return instance;
}
}
public class Singleton {
public static void main(String[] args) {
MySingleton instance = MySingleton.getInstance();
MySingleton instance1 = MySingleton.getInstance();
System.out.println(instance == instance1); // true
}
}
达到了懒加载的效果,也达到了线程安全,并且效率高。
静态内部类 -- 推荐使用
package com.tensoflow.designPattern.singleton.way06;
/**
* 静态内部类
*/
class MySingleton {
// 构造器私有化,外部不能通过new关键字创建实例
private MySingleton() {}
// 静态内部类
private static class SingletonInstance {
private static final MySingleton INSTANCE = new MySingleton();
}
// 对外提供一个公有的静态方法,返回实例对象
public static MySingleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
public class Singleton {
public static void main(String[] args) {
MySingleton instance = MySingleton.getInstance();
MySingleton instance1 = MySingleton.getInstance();
System.out.println(instance == instance1); // true
}
}
线程安全,实现了延迟加载,效率高。
枚举 -- 推荐使用
package com.tensoflow.designPattern.singleton.way07;
/**
* 枚举
*/
enum MySingleton {
INSTANCE;
public void ok() {
System.out.println("ok");
}
}
public class Singleton {
public static void main(String[] args) {
MySingleton instance = MySingleton.INSTANCE;
MySingleton instance1 = MySingleton.INSTANCE;
System.out.println(instance == instance1); // true
instance.ok(); // ok
}
}
线程安全,还能防止反序列化重新创建新的对象。其它所有方法都能通过反射来破坏单例。
简单工厂模式
JDK中的Calendar类就是采用的简单工厂模式。
具体需求
有一个披萨的项目:要便于披萨种类的扩展,也要便于维护
1. 披萨的种类有很多比如GreekPizz、CheesePizz
2. 披萨的制作有prepare、bake、cut、box
3. 完成披萨店订购功能
传统方法

package com.tensoflow.designPattern.factory.simpleFactory.problem;
// 披萨商店类 相当于客户端
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
package com.tensoflow.designPattern.factory.simpleFactory.problem;
import lombok.Data;
// 披萨抽象类
@Data
public abstract class Pizza {
// 披萨名字
protected String name;
// 抽象方法:准备原材料
public abstract void prepare();
// 烘烤
public void bake() {
System.out.println(name + " baking...");
}
// 切割
public void cut() {
System.out.println(name + " cut...");
}
// 打包
public void box() {
System.out.println(name + " box...");
}
}
package com.tensoflow.designPattern.factory.simpleFactory.problem;
// 希腊披萨
public class GreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备希腊披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.simpleFactory.problem;
// 奶酪披萨
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备奶酪披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.simpleFactory.problem;
import java.util.Scanner;
// 订购披萨类
public class OrderPizza {
public OrderPizza() {
Pizza pizza = null;
String orderType;
do {
orderType = getType();
if ("greek".equals(orderType)) {
pizza = new GreekPizza();
pizza.setName("希腊披萨");
} else if ("cheese".equals(orderType)) {
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
} else {
break;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while(true);
}
// 获取输入
private String getType() {
return new Scanner(System.in).nextLine();
}
}
问题分析:上述代码违反了开闭原则,当我们增加一个披萨种类的时候要修改使用方代码即创建Pizze的OrderPizza类。如果在其它地方也要使用创建Pizza的代码,意味着需要多处修改。
解决方案:把创建Pizza对象封装到一个类中,这样有新的Pizza种类时,只需要修改该类就可。其它有创建Pizza对象的代码就不需要修改了即简单工厂模式。
简单工厂模式
简单工厂模式属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。定义一个创建对象的类,由这个类来封装另一个类实例化对象的行为。在软件开发中,当我们会用到大量的创建某一类或者某批对象时,就会使用工厂模式。

package com.tensoflow.designPattern.factory.simpleFactory.improve1;
// 披萨商店类 相当于客户端
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
package com.tensoflow.designPattern.factory.simpleFactory.problem;
import lombok.Data;
// 披萨抽象类
@Data
public abstract class Pizza {
// 披萨名字
protected String name;
// 抽象方法:准备原材料
public abstract void prepare();
// 烘烤
public void bake() {
System.out.println(name + " baking...");
}
// 切割
public void cut() {
System.out.println(name + " cut...");
}
// 打包
public void box() {
System.out.println(name + " box...");
}
}
package com.tensoflow.designPattern.factory.simpleFactory.problem;
// 希腊披萨
public class GreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备希腊披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.simpleFactory.problem;
// 奶酪披萨
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备奶酪披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.simpleFactory.improve1;
public class SimpleFactory {
// 根据orderType创建对应Pizza
public static Pizza CreatePizza(String orderType){
Pizza pizza = null;
if ("greek".equals(orderType)) {
pizza = new GreekPizza();
pizza.setName("希腊披萨");
} else if ("cheese".equals(orderType)) {
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
}
return pizza;
}
}
package com.tensoflow.designPattern.factory.simpleFactory.improve1;
import java.util.Scanner;
// 订购披萨类
public class OrderPizza {
// 构造器
public OrderPizza() {
String orderType = "";
do {
orderType = getType();
Pizza pizza = SimpleFactory.CreatePizza(orderType);
if (null == pizza) {
break;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while(true);
}
// 获取输入
private String getType() {
return new Scanner(System.in).nextLine();
}
}
工厂方法模式
新需求:
客户在点披萨时可以点不同口味的披萨。比如北京的奶酪披萨、北京的胡椒披萨、伦敦的奶酪披萨、伦敦的胡椒披萨。

package com.tensoflow.designPattern.factory.factoryMethod;
import com.tensoflow.designPattern.factory.simpleFactory.improve1.OrderPizza;
// 披萨商店类 相当于客户端
public class PizzaStore {
public static void main(String[] args) {
// 创建北京口味的各种披萨
new BJOrderPizza();
// 创建伦敦口味的各种披萨
new LDOrderPizza();
}
}
package com.tensoflow.designPattern.factory.factoryMethod;
import lombok.Data;
// 披萨抽象类
@Data
public abstract class Pizza {
// 披萨名字
protected String name;
// 抽象方法:准备原材料
public abstract void prepare();
// 烘烤
public void bake() {
System.out.println(name + " baking...");
}
// 切割
public void cut() {
System.out.println(name + " cut...");
}
// 打包
public void box() {
System.out.println(name + " box...");
}
}
package com.tensoflow.designPattern.factory.factoryMethod;
import com.tensoflow.designPattern.factory.simpleFactory.improve1.Pizza;
// 奶酪披萨
public class BJCheesePizza extends Pizza {
@Override
public void prepare() {
setName("北京奶酪披萨");
System.out.println("准备北京奶酪披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.factoryMethod;
import com.tensoflow.designPattern.factory.simpleFactory.improve1.Pizza;
// 希腊披萨
public class BJGreekPizza extends Pizza {
@Override
public void prepare() {
setName("北京希腊披萨");
System.out.println("准备北京希腊披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.factoryMethod;
import com.tensoflow.designPattern.factory.simpleFactory.improve1.Pizza;
// 奶酪披萨
public class LDCheesePizza extends Pizza {
@Override
public void prepare() {
setName("伦敦奶酪披萨");
System.out.println("准备伦敦奶酪披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.factoryMethod;
import com.tensoflow.designPattern.factory.simpleFactory.improve1.Pizza;
// 希腊披萨
public class LDGreekPizza extends Pizza {
@Override
public void prepare() {
setName("伦敦希腊披萨");
System.out.println("准备伦敦希腊披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.factoryMethod;
import com.tensoflow.designPattern.factory.simpleFactory.improve1.Pizza;
import java.util.Scanner;
// 订购披萨类
public abstract class OrderPizza {
// 抽象方法,让各个工厂子类自己实现
abstract Pizza createPizza(String orderType);
// 构造器
public OrderPizza() {
Pizza pizza = null;
String orderType = "";
do {
orderType = getType();
// 抽象方法由工厂子类完成
pizza = createPizza(orderType);
if (null == pizza) {
break;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while(true);
}
// 获取输入
private String getType() {
return new Scanner(System.in).nextLine();
}
}
package com.tensoflow.designPattern.factory.factoryMethod;
import com.tensoflow.designPattern.factory.simpleFactory.improve1.Pizza;
public class LDOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String orderType) {
Pizza pizza = null;
if ("greek".equals(orderType)) {
pizza = new LDGreekPizza();
} else if ("cheese".equals(orderType)) {
pizza = new LDCheesePizza();
}
return pizza;
}
}
package com.tensoflow.designPattern.factory.factoryMethod;
import com.tensoflow.designPattern.factory.simpleFactory.improve1.Pizza;
public class BJOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String orderType) {
Pizza pizza = null;
if ("greek".equals(orderType)) {
pizza = new BJGreekPizza();
} else if ("cheese".equals(orderType)) {
pizza = new BJCheesePizza();
}
return pizza;
}
}
抽象工厂模式
定义一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类。抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。从设计层面上看,抽象工厂模式就是对简单工厂模式的改进或者称为进一步的抽象。

package com.tensoflow.designPattern.factory.abstractFactory;
// 披萨商店类 相当于客户端
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza(new BJFactory());
new OrderPizza(new LDFactory());
}
}
package com.tensoflow.designPattern.factory.abstractFactory;
import lombok.Data;
// 披萨抽象类
@Data
public abstract class Pizza {
// 披萨名字
protected String name;
// 抽象方法:准备原材料
public abstract void prepare();
// 烘烤
public void bake() {
System.out.println(name + " baking...");
}
// 切割
public void cut() {
System.out.println(name + " cut...");
}
// 打包
public void box() {
System.out.println(name + " box...");
}
}
package com.tensoflow.designPattern.factory.abstractFactory;
// 奶酪披萨
public class BJCheesePizza extends Pizza {
@Override
public void prepare() {
setName("北京奶酪披萨");
System.out.println("准备北京奶酪披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.abstractFactory;
// 希腊披萨
public class BJGreekPizza extends Pizza {
@Override
public void prepare() {
setName("北京希腊披萨");
System.out.println("准备北京希腊披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.abstractFactory;
// 奶酪披萨
public class LDCheesePizza extends Pizza {
@Override
public void prepare() {
setName("伦敦奶酪披萨");
System.out.println("准备伦敦奶酪披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.abstractFactory;
// 希腊披萨
public class LDGreekPizza extends Pizza {
@Override
public void prepare() {
setName("伦敦希腊披萨");
System.out.println("准备伦敦希腊披萨原材料...");
}
}
package com.tensoflow.designPattern.factory.abstractFactory;
// 抽象工厂模式抽象层
public interface AbstractFactory {
public Pizza createPizza(String orderType);
}
package com.tensoflow.designPattern.factory.abstractFactory;
public class BJFactory implements AbstractFactory {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if ("greek".equals(orderType)) {
pizza = new BJCheesePizza();
} else if ("cheese".equals(orderType)) {
pizza = new BJGreekPizza();
}
return pizza;
}
}
package com.tensoflow.designPattern.factory.abstractFactory;
public class LDFactory implements AbstractFactory {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if ("greek".equals(orderType)) {
pizza = new LDCheesePizza();
} else if ("cheese".equals(orderType)) {
pizza = new LDGreekPizza();
}
return pizza;
}
}
package com.tensoflow.designPattern.factory.abstractFactory;
import java.util.Scanner;
// 订购披萨类
public class OrderPizza {
public AbstractFactory factory;
// 构造器
public OrderPizza(AbstractFactory factory) {
this.factory = factory;
Pizza pizza = null;
String orderType = "";
do {
orderType = getType();
pizza = factory.createPizza(orderType);
if (null == pizza) {
break;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while(true);
}
// 获取输入
private String getType() {
return new Scanner(System.in).nextLine();
}
}
原型模式
需求:
现在有一只羊。姓名:tom,年龄:1,颜色:白色。请编写程序创建和tom羊属性完全相同的10只羊。
传统方法
package com.tensoflow.designPattern.prototype.problem;
public class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep("tom", 1, "白色");
Sheep sheep1 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep2 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep3 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep4 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep5 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
System.out.println(sheep);
System.out.println(sheep1);
System.out.println(sheep2);
System.out.println(sheep3);
System.out.println(sheep4);
System.out.println(sheep5);
}
}
package com.tensoflow.designPattern.prototype.problem;
import lombok.Data;
@Data
public class Sheep {
private String name;
private Integer age;
private String color;
public Sheep(String name, Integer age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
}
优点是比较好理解,简单易操作。但是在创建新对象时,总是需要重新获取原始对象的属性,如果创建的对象比较复杂时,效率较低。
原型模式
原型模式(Prototype)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象。Java中Object类是所有类的父类,Object类提供了一个clone()方法。该方法可以将一个Java对象复制一份,但是需要实现clone的java类必须要实现一个接口Cloneable,该接口表示该类能够复制且具有复制的能力。Spring中原型Bean的创建就是原型模式。
应用场景:
- 当你有一个配置类 / 常量类(不可变对象),需要基于它做少量修改生成新对象时,直接克隆后修改比重新new并逐个赋值更高效。
- 需要记录对象在某个时间点的状态(快照),后续操作不影响历史状态。典型如编辑器的撤销、游戏存档、数据审计
- 多线程环境下的对象隔离。多线程共享一个对象时,如果某个线程需要修改对象数据,但又不想影响其他线程的读取,可克隆出独立副本供当前线程操作。
package com.tensoflow.designPattern.prototype.improve1;
public class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep("tom", 1, "白色");
Sheep sheep1 = sheep.clone();
Sheep sheep2 = sheep.clone();
Sheep sheep3 = sheep.clone();
Sheep sheep4 = sheep.clone();
Sheep sheep5 = sheep.clone();
System.out.println(sheep);
System.out.println(sheep1);
System.out.println(sheep2);
System.out.println(sheep3);
System.out.println(sheep4);
System.out.println(sheep5);
}
}
package com.tensoflow.designPattern.prototype.improve1;
import lombok.Data;
@Data
public class Sheep implements Cloneable {
private String name;
private Integer age;
private String color;
public Sheep(String name, Integer age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
// 重写clone方法 浅拷贝
@Override
protected Sheep clone(){
try {
return (Sheep) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("克隆 Sheep 失败", e);
}
}
}
建造者模式
需求:
1. 需要盖房子:打桩、砌墙、封顶
2. 房子有各种各样的比如普通房、高楼、别墅。各种房子的过程虽然一样,但是要求不同。
3. 请编写编程,完成需求。
传统方法

package com.tensoflow.designPattern.builder.problem;
public class Client {
public static void main(String[] args) {
CommonHouse commonHouse = new CommonHouse();
commonHouse.build();
}
}
package com.tensoflow.designPattern.builder.problem;
public abstract class AbstractHouse {
// 打地基
public abstract void buildBasic();
// 砌墙
public abstract void buildWalls();
// 封顶
public abstract void roofed();
// 建造
public void build() {
buildBasic();
buildWalls();
roofed();
}
}
package com.tensoflow.designPattern.builder.problem;
public class CommonHouse extends AbstractHouse {
@Override
public void buildBasic() {
System.out.println("普通房子打地基...");
}
@Override
public void buildWalls() {
System.out.println("普通房子砌墙...");
}
@Override
public void roofed() {
System.out.println("普通房子封顶...");
}
}
优点是比较好理解,简单易操作。但是设计的程序结构过于简单,没有设计缓存层对象,程序的扩展和维护性不好。这种设计把产品和创建产品的过程封装在一起,耦合性增强了。
建造者模式
建造者模式(Builder Pattern)又叫生成器模式,是一种对象构建模式。可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。JDK中的StringBuilder类就是采用的建造者模式。
建造者模式的四个角色:
Product(产品角色):一个具体的产品对象
Builder(抽象建造者):创建一个Product对象的各个部件指定的接口或者抽象类
ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件
Director(指挥者):构建一个使用Builder接口的对象。主要用于创建一个复杂的对象。能隔离客户与对象的生产过程,还负责控制产品对象的生产过程。

package com.tensoflow.designPattern.builder.improve1;
public class Client {
public static void main(String[] args) {
HouseDirector houseDirector = new HouseDirector(new HighBuilder());
House house = houseDirector.constructHouse();
houseDirector = new HouseDirector(new CommonBuilder());
House house1 = houseDirector.constructHouse();
}
}
package com.tensoflow.designPattern.builder.improve1;
import lombok.Data;
// 产品 --> Product
@Data
public class House {
private String baise;
private String wall;
private String roofed;
}
package com.tensoflow.designPattern.builder.improve1;
// Builder --> 抽象的建造者
public abstract class HouseBuilder {
private House house = new House();
// 打地基
public abstract void buildBasic();
// 砌墙
public abstract void buildWalls();
// 封顶
public abstract void roofed();
// 建造
public House build() {
return house;
}
}
package com.tensoflow.designPattern.builder.improve1;
// 具体建造者 --> ConcreteBuilder
public class HighBuilder extends HouseBuilder {
@Override
public void buildBasic() {
System.out.println("高楼打地基20m...");
}
@Override
public void buildWalls() {
System.out.println("高楼砌墙20cm...");
}
@Override
public void roofed() {
System.out.println("高楼封顶...");
}
}
package com.tensoflow.designPattern.builder.improve1;
// 具体建造者 --> ConcreteBuilder
public class CommonBuilder extends HouseBuilder{
@Override
public void buildBasic() {
System.out.println("普通房子打地基5m...");
}
@Override
public void buildWalls() {
System.out.println("普通房子砌墙10cm...");
}
@Override
public void roofed() {
System.out.println("普通房子封顶...");
}
}
package com.tensoflow.designPattern.builder.improve1;
import lombok.Data;
// 指挥者 --> Director
@Data
public class HouseDirector {
HouseBuilder houseBuilder = null;
public HouseDirector(HouseBuilder houseBuilder){
this.houseBuilder = houseBuilder;
}
// 具体建房步骤
public House constructHouse() {
houseBuilder.buildBasic();
houseBuilder.buildWalls();
houseBuilder.roofed();
return houseBuilder.build();
}
}
结构型模式
适配器模式
适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示。主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。分为类适配器模式、对象适配器模式、接口适配器模式。SpringMVC框架中的HandlerAdapter就使用了适配器模式。
类适配器模式

package com.tensoflow.designPattern.adapter.classAdapter;
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
package com.tensoflow.designPattern.adapter.classAdapter;
public class Voltage220V {
// 输出220V电压
public int output220V() {
int src = 220;
System.out.println("电压=" + src + "v");
return src;
}
}
package com.tensoflow.designPattern.adapter.classAdapter;
public interface IVoltage5V {
public int output5V();
}
package com.tensoflow.designPattern.adapter.classAdapter;
// 适配器类
public class VoltageAdapter extends Voltage220V implements IVoltage5V {
@Override
public int output5V() {
int srcV = output220V();
int dstV = srcV / 44;
return dstV;
}
}
package com.tensoflow.designPattern.adapter.classAdapter;
public class Phone {
public void charging(IVoltage5V iVoltage5V) {
if (iVoltage5V.output5V() == 5) {
System.out.println("电压为5V可以充电...");
} else {
System.out.println("电压大于5V无法充电...");
}
}
}
对象适配器模式

package com.tensoflow.designPattern.adapter.objectAdapter;
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage220V()));
}
}
package com.tensoflow.designPattern.adapter.classAdapter;
public class Voltage220V {
// 输出220V电压
public int output220V() {
int src = 220;
System.out.println("电压=" + src + "v");
return src;
}
}
package com.tensoflow.designPattern.adapter.classAdapter;
public interface IVoltage5V {
public int output5V();
}
package com.tensoflow.designPattern.adapter.objectAdapter;
// 适配器类
public class VoltageAdapter implements IVoltage5V {
private Voltage220V voltage220V;
public VoltageAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
@Override
public int output5V() {
int dstV = 0;
if (null != voltage220V) {
int srcV = voltage220V.output220V();
dstV = srcV / 44;
}
return dstV;
}
}
package com.tensoflow.designPattern.adapter.objectAdapter;
public class Phone {
public void charging(IVoltage5V iVoltage5V) {
if (iVoltage5V.output5V() == 5) {
System.out.println("电压为5V可以充电...");
} else {
System.out.println("电压不正确无法充电...");
}
}
}
接口适配器模式
当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。适用于一个接口不想使用其所有方法的情况。

package com.tensoflow.designPattern.adapter.interfaceAdapter;
public class Client {
public static void main(String[] args) {
AbstractAdapter adapter = new AbstractAdapter() {
// 只需要去重写我们需要使用的方法
@Override
public void method1() {
System.out.println("我只想使用method1方法");
}
};
adapter.method1();
}
}
package com.tensoflow.designPattern.adapter.interfaceAdapter;
public interface IInterface {
public void method1();
public void method2();
public void method3();
public void method4();
}
package com.tensoflow.designPattern.adapter.interfaceAdapter;
public abstract class AbstractAdapter implements IInterface {
public void method1() {}
public void method2() {}
public void method3() {}
public void method4() {}
}
桥接模式
桥接模式(Bridge模式)是指:将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变。JDBC中的Driver接口就使用了桥接模式。

package com.tensoflow.designPattern.birdge.improve1;
public class Client {
public static void main(String[] args) {
Phone xiaoMiPhone = new FoldedPhone(new XiaoMi());
xiaoMiPhone.open();
xiaoMiPhone.close();
xiaoMiPhone.call();
System.out.println("========================");
Phone vivoPhone = new UpRightPhone(new Vivo());
vivoPhone.open();
vivoPhone.close();
vivoPhone.call();
}
}
package com.tensoflow.designPattern.birdge.improve1;
public interface Brand {
void open();
void close();
void call();
}
package com.tensoflow.designPattern.birdge.improve1;
public class Vivo implements Brand{
@Override
public void open() {
System.out.println("Vivo手机开机");
}
@Override
public void close() {
System.out.println("Vivo手机关机");
}
@Override
public void call() {
System.out.println("Vivo手机打电话");
}
}
package com.tensoflow.designPattern.birdge.improve1;
public class XiaoMi implements Brand{
@Override
public void open() {
System.out.println("小米手机开机");
}
@Override
public void close() {
System.out.println("小米手机关机");
}
@Override
public void call() {
System.out.println("小米手机打电话");
}
}
package com.tensoflow.designPattern.birdge.improve1;
public abstract class Phone {
// 聚合品牌
private Brand brand;
public Phone(Brand brand) {
this.brand = brand;
}
protected void open() {
this.brand.open();
}
protected void close() {
this.brand.close();
}
protected void call() {
this.brand.call();
}
}
package com.tensoflow.designPattern.birdge.improve1;
public class FoldedPhone extends Phone {
public FoldedPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("折叠样式手机");
}
public void close() {
super.close();
System.out.println("折叠样式手机");
}
public void call() {
super.call();
System.out.println("折叠样式手机");
}
}
package com.tensoflow.designPattern.birdge.improve1;
public class UpRightPhone extends Phone{
public UpRightPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("直立样式手机");
}
public void close() {
super.close();
System.out.println("直立样式手机");
}
public void call() {
super.call();
System.out.println("直立样式手机");
}
}
装饰者模式
装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,符合开闭原则。Java的IO流中的FilterInputStream就是装饰者模式。
星巴克咖啡订单项目需求
1. 咖啡种类:Espresso、ShortBlack、LongBlack、Decaf
2. 调料:Milk、Soy(豆浆)、Chocolate
3. 要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便
4. 使用面向对象来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以单品咖啡 + 调料组合

package com.tensoflow.designPattern.structure.decorator.improve1;
public class Client {
public static void main(String[] args) {
// 单点LongBlack咖啡
Drink coffee = new LongBlack();
System.out.println(coffee.cost());
System.out.println(coffee.getDescription());
// 向LongBlack咖啡中增加Chocolate
coffee = new Chocolate(coffee);
System.out.println(coffee.cost());
System.out.println(coffee.getDescription());
// 向LongBlack咖啡中增加Milk
coffee = new Milk(coffee);
System.out.println(coffee.cost());
System.out.println(coffee.getDescription());
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
import lombok.Data;
// 被装饰者
@Data
public abstract class Drink {
private String description;
private float price;
public abstract float cost();
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// Coffee父类
public class Coffee extends Drink {
@Override
public float cost() {
return super.getPrice();
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// LongBlack Coffee
public class LongBlack extends Coffee {
public LongBlack() {
setDescription("LongBlack Coffee");
setPrice(12f);
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// ShortBlack Coffee
public class ShortBlack extends Coffee {
public ShortBlack() {
setDescription("ShortBlack Coffee");
setPrice(10f);
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// Decaf Coffee
public class Decaf extends Coffee {
public Decaf() {
setDescription("Decaf Coffee");
setPrice(8f);
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// Espresso Coffee
public class Espresso extends Coffee{
public Espresso() {
setDescription("Espresso Coffee");
setPrice(7.5f);
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// 装饰者
public class Decorator extends Drink {
private Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
public float cost() {
return super.getPrice() + drink.cost();
}
public String getDescription() {
return drink.getDescription() + " " + super.getDescription();
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// Chocolate调料
public class Chocolate extends Decorator{
public Chocolate(Drink drink) {
super(drink);
setDescription("Add Chocolate");
setPrice(2f);
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// Milk 调料
public class Milk extends Decorator{
public Milk(Drink drink) {
super(drink);
setDescription("Add Mike");
setPrice(2.5f);
}
}
package com.tensoflow.designPattern.structure.decorator.improve1;
// Soy 调料
public class Soy extends Decorator{
public Soy(Drink drink) {
super(drink);
setDescription("Add Soy");
setPrice(0.5f);
}
}
组合模式
组合模式:又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示整体-部分的层次关系。Java中的HashMap就使用到了组合模式。
需求:
编写程序展示一个学校院系结构:要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。

package com.tensoflow.designPattern.structure.composite.improve1;
public class Client {
public static void main(String[] args) {
OrganizationComponent university = new University("清华大学", "中国顶级理科大学");
OrganizationComponent computerCollege = new College("计算机学院", "计算机学院");
OrganizationComponent infoEngineerCollege = new College("信息工程学院", "信息工程学院");
university.add(computerCollege);
university.add(infoEngineerCollege);
computerCollege.add(new Department("软件工程", "软件工程"));
computerCollege.add(new Department("计算机科学与技术", "计算机科学与技术"));
computerCollege.add(new Department("物联网", "物联网"));
infoEngineerCollege.add(new Department("通信工程", "通信工程"));
infoEngineerCollege.add(new Department("信息工程", "信息工程"));
university.print();
}
}
package com.tensoflow.designPattern.structure.composite.improve1;
import lombok.Data;
@Data
public abstract class OrganizationComponent {
// 名字
private String name;
// 描述
private String description;
public OrganizationComponent(String name, String description) {
this.name = name;
this.description = description;
}
protected void add(OrganizationComponent organizationComponent) {
throw new UnsupportedOperationException();
}
protected void remove(OrganizationComponent organizationComponent) {
throw new UnsupportedOperationException();
}
protected abstract void print();
}
package com.tensoflow.designPattern.structure.composite.improve1;
import java.util.ArrayList;
import java.util.List;
// 学校
public class University extends OrganizationComponent {
// 学校所包含的学院集合
List<OrganizationComponent> list = new ArrayList<>();
public University(String name, String description) {
super(name, description);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
list.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
list.remove(organizationComponent);
}
@Override
protected void print() {
System.out.println("==========" + this.getName() + "==========");
for (OrganizationComponent component: list) {
component.print();
}
}
}
package com.tensoflow.designPattern.structure.composite.improve1;
import java.util.ArrayList;
import java.util.List;
// 学院
public class College extends OrganizationComponent {
// 学院所包含的系集合
List<OrganizationComponent> list = new ArrayList<>();
public College(String name, String description) {
super(name, description);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
list.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
list.remove(organizationComponent);
}
@Override
protected void print() {
System.out.println("----------" + this.getName() + "----------");
for (OrganizationComponent component: list) {
component.print();
}
}
}
package com.tensoflow.designPattern.structure.composite.improve1;
// 系(叶子节点)
public class Department extends OrganizationComponent{
public Department(String name, String description) {
super(name, description);
}
@Override
protected void print() {
System.out.println(this.getName());
}
}
外观模式
外观模式:也叫过程模式,此模式定义了一个高层接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节。Mybatis框架中有使用到外观模式。
家庭影院需求:
DVD播放器、投影仪、自动屏幕、环绕立体声、爆米花机。要求完成使用家庭影院的功能,其过程为:
直接用遥控器统筹各设备开关
开爆米花机
放下屏幕
开投影仪
开音响
开DVD
去拿爆米花
调暗灯光
播放
观影结束后,关闭各种设备

package com.tensoflow.designPattern.structure.facade.improve1;
public class Client {
public static void main(String[] args) {
HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
homeTheaterFacade.ready();
System.out.println("==================");
homeTheaterFacade.end();
}
}
package com.tensoflow.designPattern.structure.facade.improve1;
public class DVDPlayer {
private final static DVDPlayer instance = new DVDPlayer();
private DVDPlayer() {}
public static DVDPlayer getInstance() {
return instance;
}
public void on() {
System.out.println("DVD 打开...");
}
public void off() {
System.out.println("DVD 关闭...");
}
public void play() {
System.out.println("DVD 播放...");
}
public void pause() {
System.out.println("DVD 暂停...");
}
}
package com.tensoflow.designPattern.structure.facade.improve1;
public class Popcorn {
private final static Popcorn instance = new Popcorn();
private Popcorn() {}
public static Popcorn getInstance() {
return instance;
}
public void on() {
System.out.println("Popcorn 打开...");
}
public void off() {
System.out.println("Popcorn 关闭...");
}
public void pop() {
System.out.println("Popcorn 出爆米花...");
}
}
package com.tensoflow.designPattern.structure.facade.improve1;
public class Projector {
private final static Projector instance = new Projector();
private Projector() {}
public static Projector getInstance() {
return instance;
}
public void on() {
System.out.println("Projector 打开...");
}
public void off() {
System.out.println("Projector 关闭...");
}
public void focus() {
System.out.println("Projector 聚焦...");
}
}
package com.tensoflow.designPattern.structure.facade.improve1;
public class Screen {
private final static Screen instance = new Screen();
private Screen() {}
public static Screen getInstance() {
return instance;
}
public void up() {
System.out.println("Screen 上升...");
}
public void down() {
System.out.println("Screen 下降...");
}
}
package com.tensoflow.designPattern.structure.facade.improve1;
public class Stereo {
private final static Stereo instance = new Stereo();
private Stereo() {}
public static Stereo getInstance() {
return instance;
}
public void on() {
System.out.println("Stereo 打开...");
}
public void off() {
System.out.println("Stereo 关闭...");
}
public void up() {
System.out.println("Stereo 音量调大...");
}
}
package com.tensoflow.designPattern.structure.facade.improve1;
public class TheaterLight {
private final static TheaterLight instance = new TheaterLight();
private TheaterLight() {}
public static TheaterLight getInstance() {
return instance;
}
public void on() {
System.out.println("TheaterLight 打开...");
}
public void off() {
System.out.println("TheaterLight 关闭...");
}
public void bright() {
System.out.println("TheaterLight 灯光调亮...");
}
public void dim() {
System.out.println("TheaterLight 灯光调暗...");
}
}
package com.tensoflow.designPattern.structure.facade.improve1;
public class HomeTheaterFacade {
private TheaterLight theaterLight;
private Popcorn popcorn;
private Stereo stereo;
private Projector projector;
private Screen screen;
private DVDPlayer dvdPlayer;
public HomeTheaterFacade() {
this.theaterLight = TheaterLight.getInstance();
this.popcorn = Popcorn.getInstance();
this.stereo = Stereo.getInstance();
this.projector = Projector.getInstance();
this.screen = Screen.getInstance();
this.dvdPlayer = DVDPlayer.getInstance();
}
// 影院准备工作
public void ready() {
popcorn.on();
popcorn.pop();
screen.down();
projector.on();
stereo.on();
dvdPlayer.on();
theaterLight.dim();
}
// 播放
public void play() {
dvdPlayer.play();
}
// 暂停
public void pause() {
dvdPlayer.pause();
}
// 结束
public void end() {
popcorn.off();
theaterLight.bright();
screen.up();
projector.off();
stereo.off();
dvdPlayer.off();
}
}
享元模式
享元模式能够解决重复对象的内存浪费问题,当系统中有大量相似对象,需要缓冲池时。不需要总是创建新对象,可以从缓冲池里拿。这样可以降低系统内存,同时提高效率。享元模式经典的应用场景就是池技术如String常量池、数据库连接池、线程池等。
小型的外包项目,给客户A做一个产品展示网站,客户A的朋友感觉效果不错,也希望做这样的产品展示网站,但是要求都有些不同。
1. 有客户要求以新闻的形式发布
2. 有客户要求以博客的形式发布
3. 有客户希望以微信公众号的形式发布

package com.tensoflow.designPattern.structure.flyweight.improve1;
public class Client {
public static void main(String[] args) {
User user = new User();
user.setName("张三");
WebSiteFactory factory = new WebSiteFactory();
WebSite webSite1 = factory.getWebSiteCategory("新闻");
webSite1.use(user);
WebSite webSite2 = factory.getWebSiteCategory("博客");
webSite2.use(user);
WebSite webSite3 = factory.getWebSiteCategory("微信公众号");
webSite3.use(user);
WebSite webSite4 = factory.getWebSiteCategory("博客");
webSite4.use(user);
System.out.println("网站分类总数: " + factory.getWebSiteCount());
}
}
package com.tensoflow.designPattern.structure.flyweight.improve1;
import lombok.Data;
// 外部状态
@Data
public class User {
private String name;
}
package com.tensoflow.designPattern.structure.flyweight.improve1;
public abstract class WebSite {
public abstract void use(User user);
}
package com.tensoflow.designPattern.structure.flyweight.improve1;
public class ConcreteWebSite extends WebSite {
// 网站发布形式类型
private String type;
public ConcreteWebSite(String type) {
this.type = type;
}
@Override
public void use(User user) {
System.out.println("网站的发布形式为:" + type + " " + user.getName() + "正在使用...");
}
}
package com.tensoflow.designPattern.structure.flyweight.improve1;
import java.util.HashMap;
public class WebSiteFactory {
// 集合:充当池的作用
private HashMap<String, ConcreteWebSite> pool = new HashMap<>();
public WebSite getWebSiteCategory(String type) {
if (!pool.containsKey(type)) {
pool.put(type, new ConcreteWebSite(type));
}
return (WebSite) pool.get(type);
}
public int getWebSiteCount() {
return pool.size();
}
}
代理模式
代理模式:为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象。这样做的好处是可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。代理模式有静态代理、动态代理、和CGLIB代理。
静态代理
代理对象和被代理对象都要实现一个接口,如果接口增加了一个方法,则代理对象和被代理对象都需要去实现。

package com.tensoflow.designPattern.structure.proxy.staticProxy;
public class Client {
public static void main(String[] args) {
TeacherDao teacherDao = new TeacherDao();
TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
teacherDaoProxy.teach();
}
}
package com.tensoflow.designPattern.structure.proxy.staticProxy;
public interface ITeacherDao {
void teach();
}
package com.tensoflow.designPattern.structure.proxy.staticProxy;
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("老师开始授课...");
}
}
package com.tensoflow.designPattern.structure.proxy.staticProxy;
public class TeacherDaoProxy implements ITeacherDao {
private ITeacherDao target;
public TeacherDaoProxy(ITeacherDao target) {
this.target = target;
}
@Override
public void teach() {
System.out.println("开始代理...");
target.teach();
System.out.println("代理完成");
}
}
动态代理
动态代理也叫JDK代理或者接口代理。代理对象不需要实现接口,但是目标对象要实现接口,否则不能用动态代理。代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象。

package com.tensoflow.designPattern.structure.proxy.dynamic;
public class Client {
public static void main(String[] args) {
// 创建被代理对象
ITeacherDao target = new TeacherDao();
// 给被代理对象创建代理对象
ITeacherDao proxyInstance = (ITeacherDao) new ProxyFactory(target).getProxyInstance();
// 通过代理对象调用方法
proxyInstance.teach();
}
}
package com.tensoflow.designPattern.structure.proxy.dynamic;
public interface ITeacherDao {
void teach();
}
package com.tensoflow.designPattern.structure.proxy.dynamic;
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("老师开始授课...");
}
}
package com.tensoflow.designPattern.structure.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
// 维护一个被代理对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
// 给被代理对象生成代理对象
public Object getProxyInstance() {
/*
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
参数一:ClassLoader loader:指定当前被代理对象使用的类加载器,获取加载器的方法固定
参数二:Class<?>[] interfaces:被代理对象实现的接口类型,使用泛型方法确认类型
参数三:InvocationHandler h:事件处理,执行被代理对象时会触发事件处理器方法,会把当前执行的被代理对象方法作为参数传入
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK代理开始...");
// 反射机制调用被代理对象方法
Object returnVal = method.invoke(target, args);
System.out.println("JDK代理结束...");
return returnVal;
}
});
}
}
CGLIB代理
静态代理和JDK代理都要求被代理对象实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用被代理对象子类来实现代理。如果被代理对象需要实现接口用JDK代理,目标对象不需要实现接口用CGLIB代理。其底层是通过使用字节码处理框架ASM来转换字节码并生成新的类。被代理的类不能用final修饰。被代理对象的方法如果为final/static,那么不会执行目标对象额外的业务方法。

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.3.0</version>
</dependency>
package com.tensoflow.designPattern.structure.proxy.cglib;
public class Client {
public static void main(String[] args) {
// 创建被代理对象
TeacherDao teacherDao = new TeacherDao();
// 获取代理对象
TeacherDao proxyInstance = (TeacherDao) new ProxyFactory(teacherDao).getProxyInstance();
// 调用方法
proxyInstance.teach();
}
}
package com.tensoflow.designPattern.structure.proxy.cglib;
public class TeacherDao {
public void teach() {
System.out.println("老师开始授课...");
}
}
package com.tensoflow.designPattern.structure.proxy.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory implements MethodInterceptor {
// 维护一个被代理对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
// 给被代理对象生成代理对象
public Object getProxyInstance() {
// 创建一个工具类
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(target.getClass());
// 设置回调函数
enhancer.setCallback(this);
// 创建子类对象即代理对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("Cglib代理模式开始了...");
// 调用被调用对象的方法
Object returnVal = method.invoke(target, args);
System.out.println("Cglib代理结束...");
return returnVal;
}
}
行为型模式
模板方法模式
模板方法模式又叫模板模式,在一个抽象类公开定义执行它的方法模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。简单说,模板方法模式定义一个操作中算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。
需求
1. 制作豆浆流程 选材--》添加配料--》侵泡--》豆浆机打碎
2. 通过添加不同的配料制作出不同口味的豆浆
3. 选材、侵泡和豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的

package com.tensoflow.designPattern.behavior.template;
public class Client {
public static void main(String[] args) {
// 制作红豆豆浆
SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
redBeanSoyaMilk.make();
// 制作花生豆浆
SoyaMilk pennutSoyaMilk = new PennutSoyaMilk();
pennutSoyaMilk.make();
}
}
package com.tensoflow.designPattern.behavior.template;
// 抽象类表示豆浆
public abstract class SoyaMilk {
// 模板方法: 不让子类重写
public final void make() {
select();
add();
soak();
beat();
}
// 选材料
private void select() {
System.out.println("第一步: 选择好的新鲜的黄豆...");
}
// 加配料,子类去实现
public abstract void add();
// 侵泡
private void soak() {
System.out.println("开始侵泡...");
}
// 打磨
private void beat() {
System.out.println("开始打磨...");
}
}
package com.tensoflow.designPattern.behavior.template;
public class RedBeanSoyaMilk extends SoyaMilk {
@Override
public void add() {
System.out.println("加入上好的红豆...");
}
}
package com.tensoflow.designPattern.behavior.template;
public class PennutSoyaMilk extends SoyaMilk {
@Override
public void add() {
System.out.println("加入上好的花生...");
}
}
命令模式
需求
1. 买了一套智能家电,有照明灯、风扇、冰箱、洗衣机。我们只要在手机上安装App就可以控制这些家电。
2. 这些家电来自不同厂家,不想针对每一种家电都安装一个App分别控制,只希望只要一个App就可以控制全部智能家电。

package com.tensoflow.designPattern.behavior.command.improver1;
import java.rmi.Remote;
public class Client {
public static void main(String[] args) {
// 创建电灯对象
LightReceiver lightReceiver = new LightReceiver();
// 创建电灯打开的命令
LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
// 创建电灯关闭的命令
LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
// 创建遥控器
RemoteController remoteController = new RemoteController();
// 给遥控器设置命令
remoteController.setCommand(0, lightOnCommand, lightOffCommand);
// 打开电灯
remoteController.onButtonWasPushed(0);
// 关闭电灯
remoteController.offButtonWasPushed(0);
// 撤职操作
remoteController.undoButtonWasPushed();
}
}
package com.tensoflow.designPattern.behavior.command.improver1;
// 命令接口
public interface Command {
// 执行命令
public void execute();
// 撤销命令
public void undo();
}
package com.tensoflow.designPattern.behavior.command.improver1;
public class LightReceiver {
public void on() {
System.out.println("电灯打开...");
}
public void off() {
System.out.println("电灯关闭...");
}
}
package com.tensoflow.designPattern.behavior.command.improver1;
public class LightOnCommand implements Command{
LightReceiver light;
public LightOnCommand(LightReceiver light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
package com.tensoflow.designPattern.behavior.command.improver1;
public class LightOffCommand implements Command{
LightReceiver light;
public LightOffCommand(LightReceiver light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
package com.tensoflow.designPattern.behavior.command.improver1;
// 空执行: 用于初始化每个按钮,当调用命令时,对象什么都不做
// 这也是一种设计模式,可以省掉对null的判断
public class NoCommand implements Command{
@Override
public void execute() {}
@Override
public void undo() {}
}
package com.tensoflow.designPattern.behavior.command.improver1;
public class RemoteController {
// 开按钮的命令数组
Command[] onCommands;
Command[] offCommands;
// 执行撤销命令
Command undoCommand;
public RemoteController() {
onCommands = new Command[5];
offCommands = new Command[5];
for (int i = 0; i < 5; i++) {
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
}
// 给按钮设置需要的命令
public void setCommand(int no, Command onCommand, Command offCommand) {
onCommands[no] = onCommand;
offCommands[no] = offCommand;
}
// 按下开按钮
public void onButtonWasPushed(int no) {
// 找到按下的开的按钮,并执行方法
onCommands[no].execute();
// 记录这次操作,用于撤销
undoCommand = onCommands[no];
}
// 按下关按钮
public void offButtonWasPushed(int no) {
// 找到按下的关的按钮,并执行方法
offCommands[no].execute();
// 记录这次操作,用于撤销
undoCommand = offCommands[no];
}
// 按下撤销按钮
public void undoButtonWasPushed() {
undoCommand.undo();
}
}
访问者模式
访问者模式:封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
需求:
将观众分为男人和女人,对歌手进行测评,当看完某个歌手表演后,得到他们对该歌手不同的评价。

package com.tensoflow.designPattern.behavior.visitor.improve1;
public class Client {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.attach(new Man());
objectStructure.attach(new Woman());
Success success = new Success();
objectStructure.display(success);
Fail fail = new Fail();
objectStructure.display(fail);
}
}
package com.tensoflow.designPattern.behavior.visitor.improve1;
public abstract class Action {
// 得到男性测评结果
public abstract void getManResult(Man man);
// 得到女性测评结果
public abstract void getWomanResult(Woman woman);
}
package com.tensoflow.designPattern.behavior.visitor.improve1;
public class Success extends Action{
@Override
public void getManResult(Man man) {
System.out.println("男人的评价是很成功...");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println("女人的评价是很成功...");
}
}
package com.tensoflow.designPattern.behavior.visitor.improve1;
public class Fail extends Action{
@Override
public void getManResult(Man man) {
System.out.println("男人的评价是失败...");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println("女人的评价是失败...");
}
}
package com.tensoflow.designPattern.behavior.visitor.improve1;
public abstract class Person {
public abstract void accept(Action action);
}
package com.tensoflow.designPattern.behavior.visitor.improve1;
public class Woman extends Person{
@Override
public void accept(Action action) {
action.getWomanResult(this);
}
}
package com.tensoflow.designPattern.behavior.visitor.improve1;
public class Man extends Person{
@Override
public void accept(Action action) {
action.getManResult(this);
}
}
package com.tensoflow.designPattern.behavior.visitor.improve1;
import java.util.LinkedList;
import java.util.List;
public class ObjectStructure {
private List<Person> elements = new LinkedList<>();
public void attach(Person person) {
elements.add(person);
}
public void detach(Person person) {
elements.remove(person);
}
public void display(Action action) {
for (Person person: elements) {
person.accept(action);
}
}
}
迭代器模式
迭代器模式:提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示。
需求:
编写程序展示一个学校院系结构:要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。

package com.tensoflow.designPattern.behavior.iterator.improve1;
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args) {
List<College> list = new ArrayList<>();
ComputerCollege computerCollege = new ComputerCollege();
InfoCollege infoCollege = new InfoCollege();
list.add(computerCollege);
list.add(infoCollege);
OutPutImpl outPut = new OutPutImpl(list);
outPut.printCollege();
}
}
package com.tensoflow.designPattern.behavior.iterator.improve1;
import java.util.Iterator;
// 学院
public interface College {
public String getName();
// 增加系
public void addDepartment(String name, String description);
// 返回一个迭代器
public Iterator createIterator();
}
package com.tensoflow.designPattern.behavior.iterator.improve1;
import java.util.Iterator;
public class ComputerCollege implements College {
Department[] departments;
int numOfDepartment = 0;
public ComputerCollege() {
departments = new Department[5];
addDepartment("Java专业", "Java专业");
addDepartment("JavaScript专业", "JavaScript专业");
addDepartment("C语言专业", "C语言专业");
}
@Override
public String getName() {
return "计算机学院";
}
@Override
public void addDepartment(String name, String description) {
Department department = new Department(name, description);
departments[numOfDepartment++] = department;
}
@Override
public Iterator createIterator() {
return new ComputerCollegeIterator(departments);
}
}
package com.tensoflow.designPattern.behavior.iterator.improve1;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class InfoCollege implements College{
List<Department> list;
public InfoCollege() {
list = new ArrayList<>();
addDepartment("信息安全专业", "信息安全专业");
addDepartment("网络安全专业", "网络安全专业");
addDepartment("服务器安全专业", "服务器安全专业");
}
@Override
public String getName() {
return "信息工程学院";
}
@Override
public void addDepartment(String name, String description) {
Department department = new Department(name, description);
list.add(department);
}
@Override
public Iterator createIterator() {
return new InfoCollegeIterator(list);
}
}
package com.tensoflow.designPattern.behavior.iterator.improve1;
import java.util.Iterator;
public class ComputerCollegeIterator implements Iterator {
Department[] departments;
int position = 0;
public ComputerCollegeIterator(Department[] departments) {
this.departments = departments;
}
@Override
public boolean hasNext() {
while (position < departments.length && departments[position] == null) {
position++;
}
return position < departments.length;
}
@Override
public Department next() {
return departments[position++];
}
}
package com.tensoflow.designPattern.behavior.iterator.improve1;
import java.util.Iterator;
import java.util.List;
public class InfoCollegeIterator implements Iterator {
List<Department> list;
int index = 0;
public InfoCollegeIterator(List<Department> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return index < list.size();
}
@Override
public Object next() {
return list.get(index++);
}
}
package com.tensoflow.designPattern.behavior.iterator.improve1;
import lombok.Data;
// 系
@Data
public class Department {
private String name;
private String description;
public Department(String name, String description) {
this.name = name;
this.description = description;
}
}
package com.tensoflow.designPattern.behavior.iterator.improve1;
import java.util.Iterator;
import java.util.List;
public class OutPutImpl {
List<College> collegeList;
public OutPutImpl(List<College> collegeList) {
this.collegeList = collegeList;
}
public void printCollege() {
Iterator<College> iterator = collegeList.iterator();
while(iterator.hasNext()) {
College college = iterator.next();
// 输出学院
System.out.println("=========" + college.getName() + "=========");
// 输出系
printDepartment(college.createIterator());
}
}
// 学院输出系
public void printDepartment(Iterator iterator) {
while(iterator.hasNext()) {
Department department = (Department) iterator.next();
System.out.println(department.getName());
}
}
}
观察者模式
需求:
1.气象站可以将每天测量到的温度、湿度、气压等以公告的形式发布出去
2.需要设计开放型API,便于其它第三方也能接入气象站获取数据
3.提供温度、气压、湿度的接口
4.测量数据更新时,要能实时通知给第三方

package com.tensoflow.designPattern.behavior.observer.improve1;
public class Client {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
// 创建观察者
CurrentConditions currentConditions = new CurrentConditions();
BaiduSite baiduSite = new BaiduSite();
// 注册观察者
weatherData.registerObserver(currentConditions);
weatherData.registerObserver(baiduSite);
weatherData.setData(10f, 100f, 30.3f);
}
}
package com.tensoflow.designPattern.behavior.observer.improve1;
public interface Subject {
public void registerObserver(Observer observer);
public void remove(Observer observer);
public void notifyObservers();
}
package com.tensoflow.designPattern.behavior.observer.improve1;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class WeatherData implements Subject{
private float temperature;
private float pressure;
private float humidity;
private List<Observer> list = new ArrayList<>();
// 数据更新
public void setData(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
notifyObservers();
}
// 注册
@Override
public void registerObserver(Observer observer) {
list.add(observer);
}
// 移除
@Override
public void remove(Observer observer) {
if (list.contains(observer)) {
list.remove(observer);
}
}
// 通知
@Override
public void notifyObservers() {
for(Observer observer : list) {
observer.update(this.temperature, this.pressure, this.humidity);
}
}
}
package com.tensoflow.designPattern.behavior.observer.improve1;
public interface Observer {
public void update(float temperature, float pressure, float humidity);
}
package com.tensoflow.designPattern.behavior.observer.improve1;
public class BaiduSite implements Observer {
private float temperature;
private float pressure;
private float humidity;
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("BaiduSite Today temperature: " + temperature);
System.out.println("BaiduSite Today pressure: " + pressure);
System.out.println("BaiduSite Today humidity: " + humidity);
}
}
package com.tensoflow.designPattern.behavior.observer.improve1;
import lombok.Data;
@Data
public class CurrentConditions implements Observer {
private float temperature;
private float pressure;
private float humidity;
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("CurrentConditions Today temperature: " + temperature);
System.out.println("CurrentConditions Today pressure: " + pressure);
System.out.println("CurrentConditions Today humidity: " + humidity);
}
}
中介者模式
智能家庭需求:
1.智能家庭包括各种设备:闹钟、咖啡机、电视机、窗帘等
2.主人要看电视时,各个设备可以协同工作,自动完成看电视的准备工作。
3.流程为:闹铃响起 --》咖啡机开始做咖啡 --》 窗帘自动落下 --》 电视机开始播放

package com.tensoflow.designPattern.behavior.mediator.improve1;
public class Client {
public static void main(String[] args) {
Mediator mediator = new ConcreteMediator();
Alarm alarm = new Alarm(mediator, "alarm");
CoffeeMachine coffeeMachine = new CoffeeMachine(mediator, "coffeeMachine");
Curtains curtains = new Curtains(mediator, "curtains");
Tv tV = new Tv(mediator, "Tv");
alarm.sendAlarm(0);
coffeeMachine.finishCoffee(0);
alarm.sendAlarm(1);
}
}
package com.tensoflow.designPattern.behavior.mediator.improve1;
public abstract class Mediator {
public abstract void register(String colleagueName, Colleague colleague);
public abstract void getMessage(int stateChange, String colleague);
}
package com.tensoflow.designPattern.behavior.mediator.improve1;
import java.util.HashMap;
public class ConcreteMediator extends Mediator {
private HashMap<String, Colleague> colleagueMap = new HashMap<>();
private HashMap<String, String> interMap = new HashMap<>();
@Override
public void register(String colleagueName, Colleague colleague) {
colleagueMap.put(colleagueName, colleague);
if (colleague instanceof Alarm) {
interMap.put("Alarm", colleagueName);
} else if (colleague instanceof CoffeeMachine) {
interMap.put("CoffeeMachine", colleagueName);
} else if (colleague instanceof Tv) {
interMap.put("Tv", colleagueName);
} else if (colleague instanceof Curtains) {
interMap.put("Curtains", colleagueName);
}
}
@Override
public void getMessage(int stateChange, String colleagueName) {
if (colleagueMap.get(colleagueName) instanceof Alarm) {
if (stateChange == 0) {
((CoffeeMachine) (colleagueMap.get(interMap.get("CoffeeMachine")))).startCoffee();
((Tv) (colleagueMap.get(interMap.get("Tv")))).startTv();
} else if (stateChange == 1) {
((Tv) (colleagueMap.get(interMap.get("Tv")))).stopTv();
}
} else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {
((Curtains) (colleagueMap.get(interMap.get("Curtains")))).upCurtains();
} else if (colleagueMap.get(colleagueName) instanceof Tv) {
} else if (colleagueMap.get(colleagueName) instanceof Curtains) {
}
}
}
package com.tensoflow.designPattern.behavior.mediator.improve1;
import lombok.Data;
@Data
public abstract class Colleague {
private Mediator mediator;
public String name;
public Colleague(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public abstract void sendMessage(int stateChange);
}
package com.tensoflow.designPattern.behavior.mediator.improve1;
public class Alarm extends Colleague {
public Alarm(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name, this);
}
public void sendAlarm(int stateChange) {
sendMessage(stateChange);
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
}
package com.tensoflow.designPattern.behavior.mediator.improve1;
public class CoffeeMachine extends Colleague {
public CoffeeMachine(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name, this);
}
public void finishCoffee(int stateChange) {
sendMessage(stateChange);
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
public void startCoffee() {
System.out.println("开始制作咖啡...");
}
}
package com.tensoflow.designPattern.behavior.mediator.improve1;
public class Curtains extends Colleague {
public Curtains(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name, this);
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
public void upCurtains() {
System.out.println("窗帘升起...");
}
}
package com.tensoflow.designPattern.behavior.mediator.improve1;
public class Tv extends Colleague {
public Tv(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name, this);
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
public void startTv() {
System.out.println("Tv开始工作...");
}
public void stopTv() {
System.out.println("Tv停止工作...");
}
}
备忘录模式
需求:
游戏角色有状态(state),在大战Boss前保存自身的状态,当大战Boss后,从备忘录对象恢复到大战前的状态。

package com.tensoflow.designPattern.behavior.memento.improve1;
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
originator.setState("状态1");
Caretaker caretaker = new Caretaker();
// 保存 状态1
caretaker.add(originator.saveStateMemento());
System.out.println(originator.getState());
originator.setState("状态2");
// 保存 状态2
caretaker.add(originator.saveStateMemento());
System.out.println(originator.getState());
originator.setState("状态3");
// 保存 状态3
caretaker.add(originator.saveStateMemento());
System.out.println(originator.getState());
// 恢复到状态2
originator.setState(caretaker.get(1).getState());
System.out.println(originator.getState());
}
}
package com.tensoflow.designPattern.behavior.memento.improve1;
import lombok.Data;
@Data
public class Originator {
private String state;
// 保存数据
public Memento saveStateMemento() {
return new Memento(state);
}
// 通过备忘录恢复数据
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
package com.tensoflow.designPattern.behavior.memento.improve1;
import lombok.Data;
@Data
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
}
package com.tensoflow.designPattern.behavior.memento.improve1;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class Caretaker {
private List<Memento> list = new ArrayList<>();
public void add(Memento memento) {
list.add(memento);
}
public Memento get(int index) {
return list.get(index);
}
}
解释器模式
需求:
通过解释器模式计算a + b - c的值

package com.tensoflow.designPattern.behavior.interpreter.improve1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class Client {
public static void main(String[] args) throws IOException {
String expStr = getExpStr();
HashMap<String, Integer> var = getValue(expStr);
Calculator calculator = new Calculator(expStr);
System.out.println("运算结果:" + expStr + "=" + calculator.run(var));
}
// 获得表达式
public static String getExpStr() throws IOException {
System.out.print("请输入表达式:");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
// 获得值映射
public static HashMap<String, Integer> getValue(String expStr) throws IOException {
HashMap<String, Integer> map = new HashMap<>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
for (char ch : expStr.toCharArray()) {
if (Character.isLetter(ch) && !map.containsKey(String.valueOf(ch))) {
System.out.print("请输入 " + ch + " 的值:");
String value = br.readLine();
map.put(String.valueOf(ch), Integer.parseInt(value));
}
}
return map;
}
}
package com.tensoflow.designPattern.behavior.interpreter.improve1;
import java.util.HashMap;
public abstract class Expression {
public abstract int interpreter(HashMap<String, Integer> var);
}
package com.tensoflow.designPattern.behavior.interpreter.improve1;
import java.util.HashMap;
public class VarExpression extends Expression {
private String key;
public VarExpression(String key) {
this.key = key;
}
// 根据变量返回对应值
@Override
public int interpreter(HashMap<String, Integer> var) {
return var.get(this.key);
}
}
package com.tensoflow.designPattern.behavior.interpreter.improve1;
import java.util.HashMap;
public class SymbolExpression extends Expression{
protected Expression left;
protected Expression right;
public SymbolExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
// 空实现让其子类实现
@Override
public int interpreter(HashMap<String, Integer> var) {
return 0;
}
}
package com.tensoflow.designPattern.behavior.interpreter.improve1;
import java.util.HashMap;
public class AddExpression extends SymbolExpression{
public AddExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
package com.tensoflow.designPattern.behavior.interpreter.improve1;
import java.util.HashMap;
public class SubExpression extends SymbolExpression{
public SubExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
package com.tensoflow.designPattern.behavior.interpreter.improve1;
import java.util.HashMap;
import java.util.Stack;
public class Calculator {
// 定义表达式
private Expression expression;
public Calculator(String expStr) {
Stack<Expression> stack = new Stack<>();
char[] charArray = expStr.toCharArray();
Expression left = null;
Expression right = null;
for (int i = 0; i < charArray.length; i++) {
switch (charArray[i]) {
case '+':
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new AddExpression(left, right));
break;
case '-':
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new SubExpression(left, right));
break;
default:
stack.push(new VarExpression(String.valueOf(charArray[i])));
break;
}
}
this.expression = stack.pop();
}
public int run(HashMap<String, Integer> var) {
return this.expression.interpreter(var);
}
}
状态模式
状态模式:它主要用来解决对象在多种状态转换时,需要对外输出不同行为的问题。状态和行为是一一对应的,状态之间可以相互转换。
需求:
1.假如每参加一次这个活动要扣除用户50积分,中奖概率是10%
2.奖品数量固定,抽完就不能抽奖
3.活动有四个状态:可以抽奖、不能抽奖、发放奖品、奖品领完

package com.tensoflow.designPattern.behavior.state.improve1;
public class Client {
public static void main(String[] args) {
// 创建活动对象,奖品池有1个奖品
RaffleActivity activity = new RaffleActivity(1);
// 连续抽奖
for (int i = 0; i < 100; i++) {
System.out.println("----------第" + (i + 1) + "次抽奖----------");
// 参加抽奖,第一步点击扣除积分
activity.deductMoney();
// 第二步抽奖
activity.raffle();
}
}
}
package com.tensoflow.designPattern.behavior.state.improve1;
import lombok.Data;
@Data
public class RaffleActivity {
State state = null;
int count = 0;
// 四个属性,表示四种状态
State noRafflleState = new NoRaffleState(this);
State canRaffleState = new CanRaffleState(this);
State dispenseState = new DispenseState(this);
State dispensOutState = new DispenseOutState(this);
public RaffleActivity( int count) {
this.state = getNoRafflleState();
this.count = count;
}
public void deductMoney(){
state.deductMoney();
}
public void raffle() {
if(state.raffle()) {
state.dispensePrize();
}
}
public int getCount() {
int curCount = count;
count--;
return curCount;
}
}
package com.tensoflow.designPattern.behavior.state.improve1;
public abstract class State {
// 扣除积分
public abstract void deductMoney ();
// 是否抽中奖品
public abstract boolean raffle ();
// 发放奖品
public abstract void dispensePrize ();
}
package com.tensoflow.designPattern.behavior.state.improve1;
// 不能抽奖状态
public class NoRaffleState extends State{
RaffleActivity activity;
public NoRaffleState(RaffleActivity activity) {
this.activity = activity;
}
// 当前状态可以扣积分,扣除后,将状态设置成可以抽奖状态
@Override
public void deductMoney() {
System.out.println("扣除50积分成功,您可以抽奖了");
activity.setState(activity.getCanRaffleState());
}
// 当前状态不能抽奖
@Override
public boolean raffle() {
System.out.println("扣了积分才能抽奖喔!");
return false;
}
@Override
public void dispensePrize() {
System.out.println("不能发放奖品");
}
}
package com.tensoflow.designPattern.behavior.state.improve1;
import java.util.Random;
// 能抽奖状态
public class CanRaffleState extends State {
RaffleActivity activity;
public CanRaffleState(RaffleActivity activity) {
this.activity = activity;
}
@Override
public void deductMoney() {
System.out.println("已经扣取过了积分");
}
@Override
public boolean raffle() {
System.out.println("正在抽奖,请稍等!");
Random r = new Random();
int num = r.nextInt(10);
// 10%中奖机会
if(num == 0){
// 改变活动状态为发放奖品 context
activity.setState(activity.getDispenseState());
return true;
}else{
System.out.println("很遗憾没有抽中奖品!");
// 改变状态为不能抽奖
activity.setState(activity.getNoRafflleState());
return false;
}
}
@Override
public void dispensePrize() {
System.out.println("没中奖,不能发放奖品");
}
}
package com.tensoflow.designPattern.behavior.state.improve1;
import java.util.Random;
// 奖品发送状态
public class DispenseState extends State{
RaffleActivity activity;
public DispenseState(RaffleActivity activity) {
this.activity = activity;
}
@Override
public void deductMoney() {
System.out.println("不能扣除积分");
}
@Override
public boolean raffle() {
System.out.println("不能抽奖");
return false;
}
//发放奖品
@Override
public void dispensePrize() {
if(activity.getCount() > 0){
System.out.println("恭喜中奖了");
// 改变状态为不能抽奖
activity.setState(activity.getNoRafflleState());
}else{
System.out.println("很遗憾,奖品发送完了");
// 改变状态为奖品发送完毕
activity.setState(activity.getDispensOutState());
}
}
}
package com.tensoflow.designPattern.behavior.state.improve1;
// 奖品发送完状态
public class DispenseOutState extends State{
RaffleActivity activity;
public DispenseOutState(RaffleActivity activity) {
this.activity = activity;
}
@Override
public void deductMoney() {
System.out.println("奖品发送完了,请下次再参加");
}
@Override
public boolean raffle() {
System.out.println("奖品发送完了,请下次再参加");
return false;
}
//发放奖品
@Override
public void dispensePrize() {
System.out.println("奖品发送完了,请下次再参加");
}
}
策略模式
策略模式:定义算法簇,分别封装起来,让它们之间可以互相替换。此模式让算法的变化独立于使用算法的客户。
需求:
1.有各种鸭子(野鸭、北京鸭、水鸭),鸭子有各种行为比如叫、飞行等
2.显示鸭子信息

package com.tensoflow.designPattern.behavior.strategy.improve1;
public class Client {
public static void main(String[] args) {
WildDuck wildDuck = new WildDuck();
wildDuck.fly();
PekingDuck pekingDuck = new PekingDuck();
pekingDuck.fly();
ToyDuck toyDuck = new ToyDuck();
toyDuck.fly();
}
}
package com.tensoflow.designPattern.behavior.strategy.improve1;
public abstract class Duck {
FlyBehavior flyBehavior;
public abstract void display();
public void quack() {
System.out.println("鸭子嘎嘎叫");
}
public void swim() {
System.out.println("鸭子会游泳");
}
public void fly() {
if (flyBehavior != null) {
flyBehavior.fly();
}
}
}
package com.tensoflow.designPattern.behavior.strategy.improve1;
public class PekingDuck extends Duck {
public PekingDuck() {
flyBehavior = new BadFlyBehavior();
}
@Override
public void display() {
System.out.println("北京鸭");
}
}
package com.tensoflow.designPattern.behavior.strategy.improve1;
public class ToyDuck extends Duck {
public ToyDuck() {
flyBehavior = new NoFlyBehavior();
}
@Override
public void display() {
System.out.println("玩具鸭");
}
}
package com.tensoflow.designPattern.behavior.strategy.improve1;
public class WildDuck extends Duck {
public WildDuck() {
flyBehavior = new GoodFlyBehavior();
}
@Override
public void display() {
System.out.println("野鸭");
}
}
package com.tensoflow.designPattern.behavior.strategy.improve1;
public interface FlyBehavior {
public void fly();
}
package com.tensoflow.designPattern.behavior.strategy.improve1;
public class GoodFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("飞翔技术高超");
}
}
package com.tensoflow.designPattern.behavior.strategy.improve1;
public class NoFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("不会飞翔");
}
}
package com.tensoflow.designPattern.behavior.strategy.improve1;
public class BadFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("飞翔技术一般");
}
}
职责链模式
职责链模式:为请求创建一个接受对象的链。通常每个接受者都包含对另一个接受者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接受者,以此类推。
学校OA系统的采购审批项目:需求是
1.采购员采购教学器材
2.如果金额小于等于5000,由教学主任审批
3.如果金额小于等于10000,由院长审批
4.如果金额小于等于30000,由副校长审批
5.如果金额超过30000以上,由校长审批

package com.tensoflow.designPattern.behavior.responsibilityChain.improve1;
public class Client {
public static void main(String[] args) {
// 创建请求
PurchaseRequest purchaseRequest = new PurchaseRequest(1, 1000, 1);
// 创建审批人
DepartmentApprover departmentApprover = new DepartmentApprover("张主任");
CollegeApprover collegeApprover = new CollegeApprover("李院长");
ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校长");
SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("刘校长");
// 设置审批流程
departmentApprover.setApprover(collegeApprover);
collegeApprover.setApprover(viceSchoolMasterApprover);
viceSchoolMasterApprover.setApprover(schoolMasterApprover);
schoolMasterApprover.setApprover(departmentApprover);
departmentApprover.processRequest(purchaseRequest);
}
}
package com.tensoflow.designPattern.behavior.responsibilityChain.improve1;
import lombok.Data;
// 请求类
@Data
public class PurchaseRequest {
private int type = 0;
private float price = 0.0f;
private int id = 0;
public PurchaseRequest(int type, float price, int id) {
this.type = type;
this.price = price;
this.id = id;
}
}
package com.tensoflow.designPattern.behavior.responsibilityChain.improve1;
import lombok.Data;
@Data
public abstract class Approver {
// 下一个处理者
Approver approver;
// 名字
String name;
public Approver(String name) {
this.name = name;
}
public abstract void processRequest(PurchaseRequest purchaseRequest);
}
package com.tensoflow.designPattern.behavior.responsibilityChain.improve1;
public class DepartmentApprover extends Approver {
public DepartmentApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() <= 5000) {
System.out.println("请求编号 id = " + purchaseRequest.getId() + " 的请求被" + this.name + "处理了");
} else {
this.approver.processRequest(purchaseRequest);
}
}
}
package com.tensoflow.designPattern.behavior.responsibilityChain.improve1;
public class CollegeApprover extends Approver {
public CollegeApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() >= 5000 && purchaseRequest.getPrice() <= 10000) {
System.out.println("请求编号 id = " + purchaseRequest.getId() + " 的请求被" + this.name + "处理了");
} else {
this.approver.processRequest(purchaseRequest);
}
}
}
package com.tensoflow.designPattern.behavior.responsibilityChain.improve1;
public class ViceSchoolMasterApprover extends Approver {
public ViceSchoolMasterApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() > 10000 && purchaseRequest.getPrice() <= 30000) {
System.out.println("请求编号 id = " + purchaseRequest.getId() + " 的请求被" + this.name + "处理了");
} else {
this.approver.processRequest(purchaseRequest);
}
}
}
package com.tensoflow.designPattern.behavior.responsibilityChain.improve1;
public class SchoolMasterApprover extends Approver {
public SchoolMasterApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() > 30000) {
System.out.println("请求编号 id = " + purchaseRequest.getId() + " 的请求被" + this.name + "处理了");
} else {
this.approver.processRequest(purchaseRequest);
}
}
}
