设计模式目的
为了让程序有更好的一下特性:
- 可读性
- 代码重用性
- 可扩展性(可维护性):方便增加功能
- 可靠性:增加功能不影响原先的功能
- 高内聚、低耦合
设计模式核心思想
把应用中可能发生变化的代码独立出来,不与不需要变化的代码混合。
设计模式原则
设计模式依据的原则
单一职责原则
一个类只负责一项职责
提高类的可读性、可扩展性
案例
public class Case1 {
//使用方
public static void main(String[] args) {
infantry solider = new infantry();
solider.action("步兵");
solider.action("指挥官");
solider.action("飞行员");
}
}
class Solider {
public void action(String solider) {
System.out.println(solider + "在陆地前线战斗!");
}
}
步兵在陆地前线战斗!
指挥官在陆地前线战斗!
飞行员在陆地前线战斗!
改进1
- 方法上遵循单一职责原则
- 修改较少
public class Case2 {
public static void main(String[] args) {
Solider solider = new Solider();
solider.action1("步兵");
solider.action2("指挥官");
}
}
class Solider {
//方法上遵循单一职责原则
public void action1(String solider) {
System.out.println(solider + "在陆地前线战斗!");
}
public void action2(String solider) {
System.out.println(solider + "指挥战斗!");
}
}
改进2
- 类中遵循单一职责原则
- 将类拆分,修改较大,需要修改客户端
public class Case3 {
//使用方
public static void main(String[] args) {
//需要修改使用方
infantry solider = new infantry();
Commander commander = new Commander();
solider.action("步兵");
commander.action("指挥官");
}
}
//将Solider类拆分,遵循单一职责原则
class infantry {
public void action(String solider) {
System.out.println(solider + "在陆地前线战斗!");
}
}
class Commander {
public void action(String solider) {
System.out.println(solider + "指挥战斗!");
}
}
类中的方法较少时考虑使用
接口隔离原则
客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上
案例
interface Interface1 {
void method1ForA();
void method2ForA();
void methodForAB();
void method1ForB();
void method2ForB();
}
class ClassA implements Interface1 {
@Override
public void method1ForA() {
}
@Override
public void method2ForA() {
}
@Override
public void methodForAB() {
}
@Override
public void method1ForB() {
}
@Override
public void method2ForB() {
}
}
class ClassB implements Interface1 {
@Override
public void method1ForA() {
}
@Override
public void method2ForA() {
}
@Override
public void methodForAB() {
}
@Override
public void method1ForB() {
}
@Override
public void method2ForB() {
}
}
class ClassNeedA {
public void depend1(Interface1 interface1) {
interface1.method1ForA();
}
public void depend2(Interface1 interface1) {
interface1.method2ForA();
}
public void depend3(Interface1 interface1) {
interface1.methodForAB();
}
}
class ClassNeedB {
public void depend1(Interface1 interface1) {
interface1.method1ForB();
}
public void depend2(Interface1 interface1) {
interface1.method2ForB();
}
public void depend3(Interface1 interface1) {
interface1.methodForAB();
}
}
改进
interface Interface2 {
void method1ForA();
void method2ForA();
}
interface Interface3 {
void method1ForB();
void method2ForB();
}
interface Interface4 {
void methodForAB();
}
class ClassA1 implements Interface2, Interface4 {
@Override
public void method1ForA() {
}
@Override
public void method2ForA() {
}
@Override
public void methodForAB() {
}
}
class ClassB1 implements Interface3, Interface4 {
@Override
public void method1ForB() {
}
@Override
public void method2ForB() {
}
@Override
public void methodForAB() {
}
}
class ClassNeedA1 {
public void depend1(Interface2 interface2) {
interface2.method1ForA();
}
public void depend2(Interface2 interface2) {
interface2.method2ForA();
}
public void depend3(Interface4 interface4) {
interface4.methodForAB();
}
}
class ClassNeedB1 {
public void depend1(Interface3 interface3) {
interface3.method1ForB();
}
public void depend3(Interface3 interface3) {
interface3.method2ForB();
}
public void depend3(Interface4 interface4) {
interface4.methodForAB();
}
}
依赖倒置原则
- 高层模块不应该依赖低层模块,二者都应该依赖其抽象
- 抽象不应该依赖细节,细节应该依赖抽象
- 中心思想:面向接口编程
- 使用抽象类、接口制定规范,而把展示细节任务交给他们的实现类
案例
public class Case1 {
public static void main(String[] args) {
SmartController smartController = new SmartController();
TV tv = new TV();
smartController.control(tv);
smartController.control(new AirConditioner());
}
}
class TV {
public String turnOn() {
return "电视开机";
}
}
class AirConditioner {
public String turnOn() {
return "空调开机";
}
}
class SmartController {
public void control(TV tv) {
System.out.println(tv.turnOn());
}
//添加一个新的方法,重载方法
public void control(AirConditioner airConditioner) {
System.out.println(airConditioner.turnOn());
}
}
增加其他家居,需要添加方法,控制器与具体的家居耦合度过高
改进
public class Case2 {
public static void main(String[] args) {
TV1 tv = new TV1();
SmartController1 smartController1 = new SmartController1();
smartController1.control(tv);//接口传递
SmartController1 smartController2 = new SmartController1(new AirConditioner1());//构造器传递
smartController2.control();
smartController2.setter(tv);//setter方法传递
smartController2.control();
}
}
interface SmartHome {
String turnOn();
}
class TV1 implements SmartHome {
public String turnOn() {
return "电视开机";
}
}
class AirConditioner1 implements SmartHome {
public String turnOn() {
return "空调开机";
}
}
class SmartController1 {
//构造器传递、setter传递所需成员变量,引用实现类对象
private SmartHome smartHome;
public SmartController1() {
}
//构造器传递所需构造器,传递实现类对象
public SmartController1(SmartHome smartHome) {
this.smartHome = smartHome;
}
//setter方法传递所需方法,传递实现类对象
public void setter(SmartHome smartHome) {
this.smartHome = smartHome;
}
//接口传递所需方法,控制实现类
public void control(SmartHome smartHome) {
System.out.println(smartHome.turnOn());
}
//构造器传递、setter传递所需方法,控制实现类
public void control() {
System.out.println(smartHome.turnOn());
}
}
抽象不应该依赖细节,细节应该依赖抽象
里氏替换原则
- 所有引用基类的地方必须能透明地使用其子类的对象
- 子类可以扩展父类的功能,但不能改变父类的功能(尽量不重写、不重载父类的方法)
- 子类可以增加特有的功能
- 子类的方法重载父类的方法时,方法的前置条件(方法的形参)要比父类方法的输入参数更宽松。
- 子类的方法实现父类的抽象方法时,方法的后置条件(方法的返回值)要比父类更严格
案例
public class Case1 {
public static void main(String[] args) {
Worker worker = new Worker();
Student student = new Student();
System.out.println("社会上使用" + worker.printInfo());
System.out.println("学校里使用" + student.printInfo());
System.out.println("社会上使用" + student.printInfo());//应该调用父类的方法获取个人信息,但方法被重写
}
}
class Worker {
public String printInfo() {
return "个人信息";
}
}
class Student extends Worker {
public String printInfo() {
return "学生信息";
}
}
违背了里氏替换原则
改进
- 不重写父类方法,而新增一个子类方法
- 父类、子类继承一个基类
- 使用组合关系,父类对象作为子类的属性
迪米特原则(最少知道原则)
- 一个对象应该对其他对象保持最少的了解,对自己依赖的类知道得越少越好
- 直接朋友:对象之间会有耦合关系,出现在成员变量、方法参数、方法返回值的类
- 陌生类不要以局部变量形式存在
案例
public class Case1 {
public static void main(String[] args) {
ArrayList<Member> members = new ArrayList<>();
Boss boss = new Boss();
for (int i = 0; i < 5; i++) {
members.add(new Member(i));
}
Leader leader = new Leader(members);
boss.getTeamInfo(leader);
}
}
class Member {
public int id;
public Member(int id) {
this.id = id;
}
}
class Leader {
private List<Member> members;
public Leader(ArrayList<Member> members) {
this.members = members;
}
public List<Member> getMembers() {
return members;
}
}
class Boss {
public void getTeamInfo(Leader leader) {
List<Member> members = leader.getMembers();//局部变量不是直接朋友
System.out.println("团队成员有:");
for (Member member : members) {
System.out.println("员工ID:" + member.id);
}
}
}
改进
public class Case2 {
public static void main(String[] args) {
ArrayList<Member> members = new ArrayList<>();
Boss boss = new Boss();
for (int i = 0; i < 5; i++) {
members.add(new Member(i));
}
Leader leader = new Leader(members);
boss.getTeamInfo(leader);
}
}
class Leader1 {
private List<Member> members;
public Leader1(ArrayList<Member> members) {
this.members = members;
}
public List<Member> getMembers() {
return members;
}
//打印信息的方法交给组长
public void printTeamInfo() {
System.out.println("团队成员有:");
for (Member member : members) {
System.out.println("员工ID:" + member.id);
}
}
}
class Boss1 {
public void getTeamInfo(Leader1 leader) {
leader.printTeamInfo();
}
}
合成复用原则
- 尽量使用合成、内聚的方式,而不使用继承
- 交互对象之间尽量做到松耦合
例子
public class Case1 {
public static void main(String[] args) {
B b = new B(new A());
b.method();
}
}
class A {
public void method1() {
System.out.println("A中方法1");
}
public void method2() {
System.out.println("A中方法2");
}
public void method3() {
System.out.println("A中方法3");
}
}
class B {
private A a;//A为B的成员变量
public B(A a) {
this.a = a;
}
public void method() {
a.method1();
a.method2();
a.method3();
}
}
开闭原则
- 一个软件实体如类、模块和函数应该对扩展开放(提供方),对修改关闭(使用方)
- 通过扩展软件实体完成变化、而不是修改现有代码
- 最基础的设计原则,遵守其他原则也就遵守开闭原则
案例
public class Case1 {
public void create(Shape shape) {
String name = shape.name;
if (name == "圆") {
createCircle();
} else if (shape.name == "长方形") {//添加其他图形需要修改代码
createRectangle();
} else {
System.out.println("未知图形");
}
}
//添加其他图形需要在使用方添加方法
public void createCircle() {
System.out.println("需要半径,以生成圆");
}
public void createRectangle() {
System.out.println("需要长、宽,以生成长方形");
}
public static void main(String[] args) {
Case1 case1 = new Case1();
case1.create(new Circle());
}
}
class Shape {
String name;
}
class Circle extends Shape {
Circle() {
name = "圆";
}
}
class Rectangle extends Shape {
Rectangle() {
name = "长方形";
}
}
改进
public class Case2 {
public void create(Shape1 shape) {
shape.create();
}
public static void main(String[] args) {
Case1 case1 = new Case1();
//对修改关闭,使用方无需修改
case1.create(new Circle());
case1.create(new Rectangle());
}
}
//对提供方扩展开放,增加其他图形时继承抽象类,重写方法
abstract class Shape1 {
String name;
abstract void create();
}
class Circle1 extends Shape1 {
Circle1() {
name = "圆";
}
@Override
void create() {
System.out.println("需要半径,以生成圆");
}
}
class Rectangle1 extends Shape1 {
Rectangle1() {
name = "长方形";
}
@Override
void create() {
System.out.println("需要长、宽,以生成长方形");
}
}
设计模式
单例模式
饿汉式
- 线程安全,确定一定会使用实例使用
- 其他方式
- 静态代码块方式初始化方式
public class SingletonTest1 {
public static void main(String[] args) {
System1 system1 = System1.getInstance();
}
}
//饿汉式
class System1 {
private static final System1 SYSTEM = new System1();
//将构造器私有化
private System1() {
}
public static System1 getInstance() {
return SYSTEM;
}
}
懒汉式
- 其他方式
- 不使用同步,线程不安全
- 同步方法,效率低
- 同步代码块,效率低
- 静态内部类:加载外部类不会加载内部类,第一次使用内部类时才加载类,并且加载类时是线程安全的
- 枚举
双重检查
public class SingletonTest2 {
public static void main(String[] args) {
System2 system = System2.getInstance();
}
}
//懒汉式,双重检查
class System2 {
private static volatile System2 system;
private System2() {
}
public static System2 getInstance() {
if (system == null) {
synchronized (System2.class) {
if (system == null) {
system = new System2();
}
}
}
return system;
}
}
内部类
public class SingletonTest3 {
public static void main(String[] args) {
}
}
class System3 {
private System3() {
}
private static final class SystemInner {
private static final System3 SYSTEM = new System3();
}
public System3 getInstance() {
return SystemInner.SYSTEM;
}
}
枚举
public class SingletonTest4 {
public static void main(String[] args) {
System4 system = System4.SYSTEM;
}
}
enum System4 {
SYSTEM
}
工厂模式
简单工厂模式
抽象工厂模式
简单工厂模式
public class PhoneFactory1 {// 简单工厂把创建者、调用者分离
public static Phone getPhone(char c) {// 对新增产品,不修改代码则无法扩展,违反开闭原则
if (c == 'A')
return new Aphone();
else if (c == 'B')
return new Bphone();
else
return null;
}
public static void main(String[] args) {
Phone phone1 = PhoneFactory1.getPhone('A');
Phone phone2 = PhoneFactory1.getPhone('B');
phone1.call();
phone2.capture();
System.out.println();
Phone phone3 = new APhoneFactory().getPhone();
Phone phone4 = new BPhoneFactory().getPhone();
phone3.call();
phone4.capture();
}
}
抽象工厂模式
public class FactoryTest2 {
public static void main(String[] args) {
APhoneFactory aPhoneFactory = new APhoneFactory();
BPhoneFactory bPhoneFactory = new BPhoneFactory();
EarPhone earPhoneA = aPhoneFactory.getEarPhone();
Phone phoneA = aPhoneFactory.getPhone();
EarPhone earPhoneB = bPhoneFactory.getEarPhone();
Phone phoneB = bPhoneFactory.getPhone();
earPhoneA.play();
earPhoneB.play();
phoneA.call();
phoneB.call();
}
}
interface PhoneFactory2 {//工厂方法模式有一组实现了相同接口的工厂类
Phone getPhone();
EarPhone getEarPhone();
}
class APhoneFactory implements PhoneFactory2 {
public Aphone getPhone() {
return new Aphone();
}
@Override
public EarPhone getEarPhone() {
return new AEarPhone();
}
}
class BPhoneFactory implements PhoneFactory2 {
public Bphone getPhone() {
return new Bphone();
}
@Override
public EarPhone getEarPhone() {
return new BEarPhone();
}
}
原型模式
- 指定创建对象的种类,通过拷贝原型创建新的对象
相关类的信息
class Phone1 implements Cloneable, Serializable {//序列化为使用序列化方式时所需要
private static final long serialVersionUID = 1L;
private String name;
private CPU cpu;
public String getName() {
return name;
}
public CPU getCpu() {
return cpu;
}
public Phone1(String name, CPU cpu) {
this.name = name;
this.cpu = cpu;
}
}
class CPU implements Cloneable, Serializable {//序列化为使用序列化方式时所需要
public String name;
public CPU(String name) {
this.name = name;
}
public CPU Clone() {//深拷贝时需要
CPU cpu = null;
try {
cpu = (CPU) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return cpu;
}
}
使用方使用
public class prototypeTest2 {
public static void main(String[] args) {
Phone1 phone = new Phone1("A", new CPU("011"));
Phone1 phone1 = phone.clone();
Phone1 phone2 = phone.clone1();
System.out.printf("%s的哈希值:%s,CPU的哈希值:%s%n", phone.getName(), phone.hashCode(), phone.getCpu().hashCode());
System.out.printf("%s的哈希值:%s,CPU的哈希值:%s%n", phone1.getName(), phone1.hashCode(), phone1.getCpu().hashCode());
System.out.printf("%s的哈希值:%s,CPU的哈希值:%s%n", phone2.getName(), phone2.hashCode(), phone2.getCpu().hashCode());
}
}
重写clone方法(浅拷贝)
public Phone clone() {
Phone phone = null;
try {
phone = (Phone) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return phone;
}
深拷贝
public Phone1 clone() {
Phone1 phone = null;
try {
phone = (Phone1) super.clone();
phone.cpu = (CPU) cpu.Clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return phone;
}
序列化深拷贝
public Phone1 clone1() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
Phone1 phone = null;
try (bos; ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(this);
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
phone = (Phone1) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return phone;
}
建造者模式
- 使用者不需要知道产品内部细节
- 产品本身与产品创建过程解耦
- 建造者之间相对独立,使用不同的建造者便可创建不同的产品
- 将复杂产品的创建分解在不同的方法中
- 增加具体的建造者、指挥者聚合抽象建造者,符合开闭原则
- 产品内部比较复杂,产品有共同点适合使用,产品间差异大不适合使用建造者
- 建造者模式按照指定蓝图创建产品(对创建的过程有要求),而工厂模式注重不同家族产品整体创建方法
public class BuilderTest1 {
public static void main(String[] args) {
Aphonebuilder aphonebuilder = new Aphonebuilder();
Bphonebuilder bphonebuilder = new Bphonebuilder();
Director director = new Director(aphonebuilder);
Phone phoneA = director.build();
System.out.println(phoneA.getPart1() + ' ' + phoneA.getPart2());
director.setBuilder(bphonebuilder);
Phone phoneB = director.build();
System.out.println(phoneB.getPart1() + ' ' + phoneB.getPart2());
}
}
class Phone {
private String part1;
private String part2;
public void setPart1(String part1) {
this.part1 = part1;
}
public void setPart2(String part2) {
this.part2 = part2;
}
public String getPart1() {
return part1;
}
public String getPart2() {
return part2;
}
}
abstract class PhoneBuilder {
protected Phone phone = new Phone();
abstract void buildPart1();
abstract void buildPart2();
public Phone getPhone() {
return phone;
}
}
class Aphonebuilder extends PhoneBuilder {
@Override
void buildPart1() {
System.out.println("A建造部分1");
phone.setPart1("A part 1");
}
@Override
void buildPart2() {
System.out.println("A建造部分2");
phone.setPart2("A part 2");
}
}
class Bphonebuilder extends PhoneBuilder {
@Override
void buildPart1() {
System.out.println("B建造部分1");
phone.setPart1("B part 2");
}
@Override
void buildPart2() {
System.out.println("B建造部分2");
phone.setPart2("B part 2");
}
}
class Director {
private PhoneBuilder phoneBuilder;
public Director(PhoneBuilder builder) {
phoneBuilder = builder;
}
public void setBuilder(PhoneBuilder phoneBuilder) {
this.phoneBuilder = phoneBuilder;
}
public Phone build() {
phoneBuilder.buildPart1();
phoneBuilder.buildPart2();
return phoneBuilder.getPhone();
}
}
适配器模式
- 作为两个不兼容的接口之间的桥梁
- 对象适配器使用关联关系(聚合)来代替继承关系,合成复用原则
角色
- 被适配者
- 适配器
- 目标:需要适配器的输出
类适配器
对象适配器
接口适配器
public class AdapterTest1 {
public static void main(String[] args) {
Outlet outlet = new Outlet();
Phone phone = new Phone();
phone.charge(new Adapter1());
phone.charge(new Adapter2(outlet));
AbstractAdapter adapter = new AbstractAdapter(outlet) {
@Override
public String output9V() {
System.out.println("适配器输入电压为" + outlet.output220V());
System.out.println("变压");
System.out.println("适配器输出电压为9V");
return "9V";
}
};
phone.charge(adapter);
}
}
class Outlet {
public String output220V() {
return "220V";
}
}
interface TypeC {
String output9V();
}
class Phone {
public void charge(TypeC typeC) {
System.out.println("手机充电电压为" + typeC.output9V());
}
}
class Adapter1 extends Outlet implements TypeC {
@Override
public String output9V() {
System.out.println("适配器输入电压为" + output220V());
System.out.println("适配器输出电压为9V");
return "9V";
}
}
对象适配器
将被适配者作为对象
class Adapter2 implements TypeC {
private Outlet outlet;
Adapter2(Outlet outlet) {
this.outlet = outlet;
}
@Override
public String output9V() {
System.out.println("适配器输入电压为" + outlet.output220V());
System.out.println("适配器输出电压为9V");
return "9V";
}
}
接口适配器
- 被适配者作为接口
interface Output {
String output9V();
String output5V();
}
abstract class AbstractAdapter implements Output, TypeC {
protected Outlet outlet;
public AbstractAdapter(Outlet outlet) {
this.outlet = outlet;
}
//以下方法为默认实现
@Override
public String output9V() {
return outlet.output220V();
}
@Override
public String output5V() {
return outlet.output220V();
}
}
桥接模式
- 将实现、抽象放在两个不同的类层面,使两个层面可以独立改变
- 有多个角度的变化情况下, 因为使用继承而导致类爆炸、扩展不灵活的问题
public class BridgeTest1 {
public static void main(String[] args) {
HighEndPhone highEndPhoneA = new HighEndPhone(new BrandA());
LowerEndPhone lowerEndPhoneB = new LowerEndPhone(new BrandB());
highEndPhoneA.run();
lowerEndPhoneB.run();
}
}
interface Brand {
String run();
}
class BrandA implements Brand {
@Override
public String run() {
return "品牌A的手机运行";
}
}
class BrandB implements Brand {
@Override
public String run() {
return "品牌B的手机运行";
}
}
abstract class Phone {
private Brand brand;
public Phone(Brand brand) {
this.brand = brand;
}
protected void run() {
System.out.println(brand.run());
}
}
class HighEndPhone extends Phone {
public HighEndPhone(Brand brand) {
super(brand);
}
@Override
protected void run() {
super.run();
System.out.println("信息:高端机");
}
}
class LowerEndPhone extends Phone {
public LowerEndPhone(Brand brand) {
super(brand);
}
@Override
protected void run() {
super.run();
System.out.println("信息:低端机");
}
}
装饰者模式
- 动态地给一个对象添加一些额外的职责使用
- 不想增加很多子类的情况下扩展类使用
public class DecoratorTest1 {
public static void main(String[] args) {
Drink drink = new MilkTeaA();//8元
drink = new IngredientA(drink);//2元
drink = new IngredientA(drink);//2元
System.out.println(drink.getName());
System.out.println(drink.cost());
}
}
abstract class Drink {
private String name;
private double price;
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(double price) {
this.price = price;
}
abstract double cost();
}
class MilkTea extends Drink {
@Override
double cost() {
return getPrice();
}
}
class MilkTeaA extends MilkTea {
public MilkTeaA() {
setName("A奶茶");
setPrice(8);
}
}
class MilkTeaB extends MilkTea {
public MilkTeaB() {
setName("B奶茶");
setPrice(10);
}
}
class Decorator extends Drink {
private Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
double cost() {
return getPrice() + drink.cost();
}
@Override
public String getName() {
return drink.getName() + " " + super.getName();
}
}
class IngredientA extends Decorator {
public IngredientA(Drink drink) {
super(drink);
setName("配料A");
setPrice(2);
}
}
class IngredientB extends Decorator {
public IngredientB(Drink drink) {
super(drink);
setName("配料B");
setPrice(4);
}
}
组合模式(部分整体模式)
- 依据树形结构组合对象
- 要求较高的抽象性
- 节点的差异大时不适合使用
角色
- 部件(Component):接口、抽象类
- 合成品(Componsite):有子部件,上层组织
- 叶子节点(Leaf):没有子部件,最底层的组织
public class CompositeTest1 {
public static void main(String[] args) {
University university = new University("大学");
College college1 = new College("计算机学院");
College college2 = new College("信息学院");
Major major1 = new Major("计算机科学与技术");
Major major2 = new Major("软件工程");
college1.add(major1);
college1.add(major2);
university.add(college1);
university.add(college2);
university.printInfo();
college1.remove(major1);
college1.printInfo();
college2.printInfo();
}
}
class University extends Component {
private List<Component> organization = new ArrayList<>();
public University(String name) {
super(name);
}
@Override
protected void add(Component component) {
organization.add(component);
}
@Override
protected void remove(Component component) {
organization.remove(component);
}
@Override
void printInfo() {
System.out.println("=====" + super.getName() + "=====");
for (Component component : organization) {
component.printInfo();
}
}
}
class College extends Component {
private List<Component> organization = new ArrayList<>();
public College(String name) {
super(name);
}
@Override
protected void add(Component component) {
organization.add(component);
}
@Override
protected void remove(Component component) {
organization.remove(component);
}
@Override
void printInfo() {
System.out.println("----------" + super.getName() + "----------");
for (Component component : organization) {
component.printInfo();
}
}
}
class Major extends Component {
public Major(String name) {
super(name);
}
@Override
void printInfo() {
System.out.println(super.getName());
}
}
外观模式(过程模式)
- 使用者只通过外观类(高层接口)控制子系统,隐藏了子系统的细节
- 减少依赖、提高灵活性,但修改不方便,不符合开闭原则
- 对于少量的子系统,不需要使用外观模式
- 使用者与子系统解耦
- 当难以维护大型遗留的系统时,可以考虑新开发一个新系统
角色
- 外观类
- 子系统
class Employee {
private Provider provider;
private Processor processor;
private Transporter transporter;
public Employee() {
provider = new Provider();
processor = new Processor();
transporter = new Transporter();
}
public void work() {
String item = provider.provide();
String product = processor.process(item);
transporter.transport(product);
}
}
class Provider {
public String provide() {
System.out.println("提供原材料");
return "原材料";
}
}
class Processor {
public String process(String item) {
System.out.println("加工" + item);
return "产品";
}
}
class Transporter {
public void transport(String product) {
System.out.println("运输" + product);
}
}
享元模式
- 系统中有大量对象
- 对象的状态大部分可以外部化
- 内部状态不会随环境的改变而改变
- 外部状态会随环境改变而改变,不可共享
- 按照内部状态分组,当把外部状态从对象中剔除出来时,那么每一组对象都可以用一个对象来代替
- 注意划分外部状态和内部状态,否则可能会引起线程安全问题
- 这些类必须有一个工厂对象加以控制
public class FlyWeightTest1 {
public static void main(String[] args) {
Server server = new Server();
WebPage page1 = server.getPage("内容1");
WebPage page2 = server.getPage("内容2");
User user1 = new User("用户1");
User user2 = new User("用户2");
User user3 = new User("用户3");
page1.visit(user1);
page1.visit(user2);
page1.visit(user3);
page2.visit(user1);
page2.visit(user2);
System.out.println("页面个数:" + server.getSize());
}
}
class Server {
private HashMap<String, WebPage> pool = new HashMap<>();
public WebPage getPage(String key) {
if (!pool.containsKey(key)) {
pool.put(key, new ConcretePage(key));
}
return pool.get(key);
}
public int getSize() {
return pool.size();
}
}
abstract class WebPage {
abstract public void visit(User user);//参数用以设置外部状态
}
class ConcretePage extends WebPage {
private String content;//内部状态
public ConcretePage(String content) {
this.content = content;
}
@Override
public void visit(User user) {
System.out.println(user.getName() + "访问页面" + content);
}
}
class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
代理模式
- 对一个目标对象提供一个替身控制目标的访问,可以在目标对象实现的基础上,增强额外的功能
角色
- 被代理类
- 代理类
静态代理
- 代理类、被代理类实现相同的接口
- 缺点:代理类需要实现被代理类的接口、可能产生很多代理类,接口增加方法时,要修改被代理类、代理类
public class ProxyTest1 {
public static void main(String[] args) {
Server server = new Server();
ProxyServer proxyServer = new ProxyServer(server);
proxyServer.run();
}
}
interface Network {
void browse();
}
class Server implements Network {
public void browse() {
System.out.println("真实的服务器浏览");
}
}
class ProxyServer implements Network {
private Network server;
public ProxyServer(Network server) {
this.server = server;
}
public void browse() {
server.browse();
}
void run() {
System.out.println("检查工作");
browse();
}
}
动态代理(接口代理)
- 代理对象不需要实现接口
- 动态在内存中构造代理对象
- 根据传入对象,返回一个代理对象
public class ProxyTest2 {
public static void main(String[] args) {
Server1 server1 = new Server1();
ProxyFactory proxyFactory = new ProxyFactory(server1);
NetWork1 proxyServer = proxyFactory.getInstance();
System.out.println("获取:" + proxyServer.browse());
}
}
interface NetWork1 {
String browse();
}
class Server1 implements NetWork1 {
@Override
public String browse() {
System.out.println("真实的浏览");
return "浏览内容";
}
}
class ProxyFactory {
private NetWork1 target;
public ProxyFactory(NetWork1 target) {
this.target = target;
}
public NetWork1 getInstance() {
return (NetWork1) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("代理服务浏览");
Object result = method.invoke(target, args);
System.out.println("代理服务完成");
return result;
});
}
}
模板方法
- 抽象类定义了算法的结构,子类可以不改变算法的结构而重新定义算法中的特定步骤
- 修改算法时只修改父类的模板方法
- 模板方法一般设置为final,使子类不可以重新模板方法
- 每一个不同的实现需要子类的实现,类的个数会增加
- 钩子方法:默认不做
public class TemplateTest1 {
public static void main(String[] args) {
Medium medium = new Medium();
MediumWell mediumWell = new MediumWell();
medium.cook();
mediumWell.cook();
}
}
abstract class BeefSteak {
final void cook() {
heatingKettle();
addOil();
putBeef();
fry();
if (needBlackPepper()) {
addBlackPepper();
}
}
void heatingKettle() {
System.out.println("热锅");
}
void addOil() {
System.out.println("加入油");
}
void putBeef() {
System.out.println("放入牛排");
}
boolean needBlackPepper() {
return true;
}
abstract void fry();
abstract void addBlackPepper();
}
class MediumWell extends BeefSteak {
@Override
void fry() {
System.out.println("大火较长时间,七分熟");
}
@Override
void addBlackPepper() {
System.out.println("加入黑椒");
}
}
class Medium extends BeefSteak {
@Override
void fry() {
System.out.println("中火较短时间,五分熟");
}
@Override
boolean needBlackPepper() {
return false;
}
@Override
void addBlackPepper() {
}
}
命令模式
- 请求发起者、请求执行者之间解耦
- 空命令省去了判断的操作
- 可能产生较多的命令类
角色
- 调用者
- 命令(抽象)
- 接收者
public class CommandTest1 {
public static void main(String[] args) {
Commander commander = new Commander();
Air air = new Air();
Army army = new Army();
commander.getCommand(new ArmyAttack(army));
commander.getCommand(new ArmyStop(army));
commander.getCommand(new AirAttack(air));
commander.getCommand(new AirStop(air));
commander.command(0);
commander.command(1);
commander.command(2);
commander.undo();
}
}
class Commander {
private ArrayList<Command> commands = new ArrayList<>();
private ArrayList<Command> commandsHistory = new ArrayList<>();
private int index = -2;
public void getCommand(Command command) {
commands.add(command);
}
public void command(int i) {
Command command = commands.get(i);
commands.get(i).execute();
commandsHistory.add(command);
index++;
}
public void undo() {
if (index >= 0) {
commandsHistory.remove(index + 1);
commandsHistory.get(index--).execute();
}
}
}
class Army {
public void attack() {
System.out.println("陆军攻击");
}
public void stop() {
System.out.println("陆军等待命令");
}
}
class Air {
public void attack() {
System.out.println("空军攻击");
}
public void stop() {
System.out.println("空军等待命令");
}
}
interface Command {
void execute();
}
class NoCommand implements Command {
@Override
public void execute() {
//没有命令执行
}
}
class ArmyAttack implements Command {
private Army army;
public ArmyAttack(Army army) {
this.army = army;
}
@Override
public void execute() {
System.out.println("陆军执行攻击命令");
army.attack();
}
}
class ArmyStop implements Command {
private Army army;
public ArmyStop(Army army) {
this.army = army;
}
@Override
public void execute() {
System.out.println("陆军执行等待命令");
army.stop();
}
}
class AirAttack implements Command {
private Air air;
public AirAttack(Air air) {
this.air = air;
}
@Override
public void execute() {
System.out.println("空军执行攻击命令");
air.attack();
}
}
class AirStop implements Command {
private Air air;
public AirStop(Air air) {
this.air = air;
}
@Override
public void execute() {
System.out.println("空军执行等待命令");
air.stop();
}
}
访问者模式
- 符合单一职责原则、易扩展
- 违反了依赖倒置原则,依赖了具体类
- 在稳定的数据结构中使用
角色
- 访问者
- 接受者
- 被访问的数据结构
public class VisitorTest1 {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.add(new CandidateA(12, 23));
objectStructure.add(new CandidateB(23, 43));
objectStructure.add(new CandidateB(78, 65));
objectStructure.add(new CandidateB(34, 53));
objectStructure.display(new ProfessionalSkillVisitor());
objectStructure.display(new SortSkillVisitor());
}
}
abstract class Candidate {
abstract void accept(Visitor visitor);
private int professionalSkill;
private int SortSkill;
public Candidate(int professionalSkill, int sortSkill) {
this.professionalSkill = professionalSkill;
SortSkill = sortSkill;
}
public int getProfessionalSkill() {
return professionalSkill;
}
public int getSortSkill() {
return SortSkill;
}
}
class CandidateA extends Candidate {
public CandidateA(int professionalSkill, int sortSkill) {
super(professionalSkill, sortSkill);
}
@Override
void accept(Visitor visitor) {
visitor.visit(this);
}
public void introduction() {
System.out.print("求职:A职业 ");
}
}
class CandidateB extends Candidate {
public CandidateB(int professionalSkill, int sortSkill) {
super(professionalSkill, sortSkill);
}
@Override
void accept(Visitor visitor) {
visitor.visit(this);
}
public void introduction() {
System.out.print("求职:B职业 ");
}
}
interface Visitor {
void visit(CandidateA candidateA);
void visit(CandidateB candidateB);
}
class ProfessionalSkillVisitor implements Visitor {
@Override
public void visit(CandidateA candidateA) {
System.out.print("专业技能访问者访问 ");
candidateA.introduction();
System.out.println("专业技能分值" + candidateA.getProfessionalSkill());
}
@Override
public void visit(CandidateB candidateB) {
System.out.print("专业技能访问者访问 ");
candidateB.introduction();
System.out.println("专业技能分值" + candidateB.getProfessionalSkill());
}
}
class SortSkillVisitor implements Visitor {
@Override
public void visit(CandidateA candidateA) {
System.out.print("软技能访问者访问 ");
candidateA.introduction();
System.out.println("软技能分值" + candidateA.getSortSkill());
}
@Override
public void visit(CandidateB candidateB) {
System.out.print("软技能访问者访问 ");
candidateB.introduction();
System.out.println("软技能分值" + candidateB.getSortSkill());
}
}
class ObjectStructure {
List<Candidate> candidates = new ArrayList<>();
public void add(Candidate candidate) {
candidates.add(candidate);
}
public void remove(Candidate candidate) {
candidates.remove(candidate);
}
public void display(Visitor visitor) {
for (Candidate candidate : candidates) {
candidate.accept(visitor);
}
}
}
迭代器模式
- 提供遍历集合元素的接口,对于不同的数据结构不需要了解底层,使用统一的方式遍历
角色
- 集合(接口)
- 迭代器(接口)
public class IteratorTest1 {
public static void main(String[] args) {
List<Department> departments = new ArrayList<>();
departments.add(new Design("设计部"));
departments.add(new Design("开发部"));
Company company = new Company(departments);
company.printInfo();
company.printDepartmentInfo(new Development("开发1部").getIterator());
}
}
class Employee {
private String name;
public Employee(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
class Company {
List<Department> departments;
public Company(List<Department> departments) {
this.departments = departments;
}
public void printInfo() {
for (Department department : departments) {
System.out.println(department.getName());
printDepartmentInfo(department.getIterator());
}
}
public void printDepartmentInfo(Iterator<Employee> department) {
while (department.hasNext()) {
System.out.println(department.next());
}
}
}
interface Department {
String getName();
void add(Employee employee);
void remove();
Iterator<Employee> getIterator();
}
class Development implements Department {
private String name;
private Employee[] employees = new Employee[5];
private int numberOfEmployee;
public Development(String name) {
this.name = name;
add(new Employee("开发部员工1"));
add(new Employee("开发部员工2"));
add(new Employee("开发部员工3"));
add(new Employee("开发部员工4"));
}
@Override
public String getName() {
return name;
}
@Override
public void add(Employee employee) {
try {
employees[numberOfEmployee++] = employee;
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
}
@Override
public void remove() {
}
@Override
public Iterator<Employee> getIterator() {
return new IteratorForDepartment(employees);
}
}
class Design implements Department {
private String name;
private List<Employee> employees = new ArrayList<>();
public Design(String name) {
this.name = name;
employees.add(new Employee("设计部员工1"));
employees.add(new Employee("设计部员工2"));
employees.add(new Employee("设计部员工3"));
employees.add(new Employee("设计部员工4"));
}
@Override
public String getName() {
return name;
}
@Override
public void add(Employee employee) {
employees.add(employee);
}
@Override
public void remove() {
}
@Override
public Iterator<Employee> getIterator() {
return new IteratorForDesign(employees);
}
}
class IteratorForDepartment implements Iterator<Employee> {
private Employee[] employees;
private int cursor = 0;
public IteratorForDepartment(Employee[] employees) {
this.employees = employees;
}
@Override
public boolean hasNext() {
return cursor < employees.length && employees[cursor] != null;
}
@Override
public Employee next() {
return employees[cursor++];
}
}
class IteratorForDesign implements Iterator<Employee> {
private int cursor;
private List<Employee> employees;
public IteratorForDesign(List<Employee> employees) {
this.employees = employees;
}
@Override
public boolean hasNext() {
return cursor < employees.size();
}
@Override
public Employee next() {
return employees.get(cursor++);
}
}
观察者模式
- 对象的状态改变,依赖者可以得到通知并更新
- 观察目标、观察者不可出现循环依赖
角色
- 推送者(观察的目标)(Subject)
- 观察者
public class ObserverTest1 {
public static void main(String[] args) {
News news = new News();
ObserverA observerA = new ObserverA();
news.addObserver(observerA);
news.addObserver(new ObserverB());
news.setNew("消息1");
news.removeObserver(observerA);
news.setNew("最新消息");
}
}
interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
class News implements Subject {
private String latestNews;
private List<Observer> observers = new ArrayList<>();
public void setNew(String news) {
latestNews = news;
update();
}
private void update() {
notifyObservers();
}
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(latestNews);
}
}
}
interface Observer {
void update(String news);
}
class ObserverA implements Observer {
private String news;
@Override
public void update(String news) {
this.news = news;
display();
}
private void display() {
System.out.println("观察者A实例获得最新消息:" + news);
}
}
class ObserverB implements Observer {
private String news;
@Override
public void update(String news) {
this.news = news;
display();
}
private void display() {
System.out.println("观察者B实例获得最新消息:" + news);
}
}
中介者模式
- 对象(类)之间直接与中介联系以跟其他对象(类)交互,达到松耦合目的
- 中介封装了对象之间的交互
- 对象之间存在比较复杂的引用关系使用
- MVC模式,Controller就是中介
- 中介的功能比较多,中介出现问题将影响到系统
角色
- 中介(抽象类)
- 同事(抽象类),指原本相互联系的多个对象
public class MediatorTest1 {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
Seller seller = new Seller(mediator, "卖方");
Buyer buyer1 = new Buyer(mediator, "买方1");
Buyer buyer2 = new Buyer(mediator, "买方2");
buyer1.sendMessage("你好。");
seller.sendMessage("你好,请讲。");
}
}
改进的可能
- 案例相当于聊天室,一方发送消息,所以人都会收到消息
- 可以改进成可以针对一方发生消息
abstract class Mediator {
public abstract void addColleague(Colleague colleague);
public abstract void reply(String source, String message);
}
class ConcreteMediator extends Mediator {
private List<Colleague> colleagues = new ArrayList<>();
@Override
public void addColleague(Colleague colleague) {
colleagues.add(colleague);
}
@Override
public void reply(String source, String message) {
for (Colleague colleague : colleagues) {
String name = colleague.getName();
if (name != source) {
System.out.printf("[%s]收到来自[%s]的消息:%s%n", name, source, message);
}
}
}
}
abstract class Colleague {
private Mediator mediator;
private String name;
public Colleague(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public Mediator getMediator() {
return mediator;
}
public String getName() {
return name;
}
abstract public void sendMessage(String msg);
}
class Buyer extends Colleague {
public Buyer(Mediator mediator, String name) {
super(mediator, name);
mediator.addColleague(this);
}
@Override
public void sendMessage(String msg) {
String name = super.getName();
System.out.println(name + ":" + msg);
getMediator().reply(name, msg);
}
}
class Seller extends Colleague {
public Seller(Mediator mediator, String name) {
super(mediator, name);
mediator.addColleague(this);
}
@Override
public void sendMessage(String msg) {
String name = super.getName();
System.out.println(name + ":" + msg);
getMediator().reply(name, msg);
}
}
备忘录模式
- 不破坏封装性的前提下,捕获对象的内部状态,以后可以恢复状态
- 类的成员变量比较多会消耗较多资源
角色
- 备忘录
- 发起者
- 守护者:维护备忘录
public static void main(String[] args) {
Caretaker caretaker = new Caretaker(5);
ChessBoard chessBoard = new ChessBoard(5);
chessBoard.display();
caretaker.addMemento(new Memento(chessBoard.getBoard()));
chessBoard.putIn(0, 0);
caretaker.addMemento(new Memento(chessBoard.getBoard()));
chessBoard.putIn(0, 1);
caretaker.addMemento(new Memento(chessBoard.getBoard()));
chessBoard.putIn(0, 2);
chessBoard.reset(caretaker.getMemento());
chessBoard.reset(caretaker.getMemento());
chessBoard.reset(caretaker.getMemento());
chessBoard.reset(caretaker.getMemento());
}
public class ChessBoard {
private char[][] board;
public ChessBoard(int size) {
board = new char[size][size];
char[] chars;
for (int i = 0; i < size; i++) {
chars = board[i];
for (int j = 0; j < size; j++) {
chars[j] = 'O';
}
}
}
public char[][] getBoard() {
int size = board.length;
char[][] board = new char[size][size];
for (int i = 0; i < size; i++) {
System.arraycopy(this.board[i], 0, board[i], 0, size);
}
return board;
}
public void putIn(int x, int y) {
if (board[x][y] == 'O') {
board[x][y] = 'X';
System.out.println("下棋");
display();
}
}
public void display() {
for (int i = 0; i < board.length; i++) {
System.out.println(Arrays.toString(board[i]));
}
System.out.println();
}
public void reset(Memento memento) {
System.out.println("悔棋");
board = memento.getMemento();
display();
}
}
需要注意成员变量为引用类型,创建备忘录时需要克隆、深拷贝
public class Memento {
private char[][] board;
public Memento(char[][] board) {
this.board = board;
}
public char[][] getMemento() {
return board;
}
}
public class Caretaker {
private ArrayDeque<Memento> queue = new ArrayDeque<>();
private int capacity;
public Caretaker(int capacity) {
this.capacity = capacity;
}
public void addMemento(Memento memento) {
if (queue.size() == capacity) {
queue.removeFirst();
}
queue.add(memento);
}
public Memento getMemento() {
Memento memento = null;
try {
memento = queue.removeLast();
} catch (NoSuchElementException e) {
e.printStackTrace();
}
return memento;
}
}
解释器模式
- 给定一语言,定义了它的文法的一种表示,定义解释器,用解释器解释语言中的句子
- 遇到有些问题多次重复出现,而且有一定的相似性和规律性可使用
- 如正则表达式
- 会引起类膨胀
- 采用递归调用
角色
- 表达式(终结符、非终结符)
- 环境类
public class InterpreterTest {
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<>();
System.out.println("定义运算符#,a#b运算为:a*b + b");
hashMap.put("a", 3);
hashMap.put("b", 4);
System.out.println(hashMap.entrySet());
Object[] objects = hashMap.keySet().toArray();
String expr = String.format("%s#%s", objects[0], objects[1]);
Content content = new Content(expr);
System.out.println("表达式:" + expr + " 结果为:" + content.run(hashMap));
}
}
public abstract class Expression {
abstract public int interpret(HashMap<String, Integer> map);
}
public abstract class SymbolExpression extends Expression {
protected Expression left;
protected Expression right;
public SymbolExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
}
public class OperatorExpression extends SymbolExpression {
public OperatorExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpret(HashMap<String, Integer> map) {
int num1 = left.interpret(map);
int num2 = right.interpret(map);
return num1 * num2 + num2;
}
}
public class VarExpression extends Expression {
String varName;
public VarExpression(String varName) {
this.varName = varName;
}
@Override
public int interpret(HashMap<String, Integer> hashMap) {
return hashMap.get(varName);
}
}
public class Content {
private Expression expression;
public Content(String expression) {
char[] chars = expression.toCharArray();
Expression left = new VarExpression(String.valueOf(chars[0]));
Expression right = new VarExpression(String.valueOf(chars[2]));
this.expression = new OperatorExpression(left, right);
}
public int run(HashMap<String, Integer> map) {
return expression.interpret(map);
}
}
状态模式
- 对象的内部状态发生变化时,允许改变其行为
- 对于使用if-else的方法优化了许多
- 会产生很多类(状态类)
角色
- 环境
- 状态(抽象类、接口)
public class StateTest {
public static void main(String[] args) {
Order order = new Order();
order.check();
order.pay();
order.receipt();
order.complete();
order.complete();//报错
}
}
public interface OrderState {
UnsupportedOperationException exception = new UnsupportedOperationException("非法操作");
default void check(Order order) {
throw exception;
}
default void pay(Order order) {
throw exception;
}
default void receipt(Order order) {
throw exception;
}
default void complete(Order order) {
throw exception;
}
String getState();
}
class Generate implements OrderState {
private String state = "待审核";
@Override
public void check(Order order) {
order.setState(new PendingPayment());
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
class PendingPayment implements OrderState {
private String state = "待付款";
@Override
public void pay(Order order) {
order.setState(new WaitDeliver());
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
class WaitDeliver implements OrderState {
private String state = "待发货";
@Override
public void receipt(Order order) {
order.setState(new WaitConfirm());
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
class WaitConfirm implements OrderState {
private String state = "待收货";
@Override
public void complete(Order order) {
order.setState(new Competed());
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
class Competed implements OrderState {
private String state = "已完成";
@Override
public String getState() {
return state;
}
}
public class Order {
private OrderState state;
public Order() {
state = new Generate();
}
public void check() {
System.out.print("当前订单状态为:" + state.getState() + "----→");
state.check(this);
printState();
}
public void pay() {
System.out.print("当前订单状态为:" + state.getState() + "----→");
state.pay(this);
printState();
}
public void receipt() {
System.out.print("当前订单状态为:" + state.getState() + "----→");
state.receipt(this);
printState();
}
public void complete() {
System.out.print("当前订单状态为:" + state.getState() + "----→");
state.complete(this);
printState();
}
public void printState() {
System.out.println(state.getState());
}
public void setState(OrderState state) {
this.state = state;
}
}
策略模式
- 使用聚合、组合而不是继承
- 算法和使用算法的客户独立
- 避免了多重判断语句
- 算法可以替换
- 多个类中的只有行为不一样时,可以使用
- 每增加一个策略都将增加一个类
角色
- 策略类(接口,多个)
- 环境类(使用策略)
public class StrategyTest {
public static void main(String[] args) {
Student student = new Student(new Study());
student.doSomething();
student.setStrategy(new Fitness());
student.doSomething();
student.setStrategy(new Game());
student.doSomething();
}
}
public interface Strategy {
void doSomething();
}
class Study implements Strategy {
@Override
public void doSomething() {
System.out.println("学习。。。");
}
}
class Fitness implements Strategy {
@Override
public void doSomething() {
System.out.println("健身。。。");
}
}
class Game implements Strategy {
@Override
public void doSomething() {
System.out.println("游戏。。。");
}
}
public class Student {
private Strategy strategy;
public Student() {
}
public Student(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void doSomething() {
strategy.doSomething();
}
}
职责链模式
- 多个对象可以处理请求,但处理的时间不确定
- 处理消息需要过滤多道
- 发送者不需要了解将传递过程,发送者和处理者解耦
- 避免使用过的判断语句
- 需要为处理者设置下一个处理者
- 不能保证处理一定会被处理
角色
- 处理者(抽象)
- 客户
public class ChainOfResponsibilityTest {
public static void main(String[] args) {
Handler instructor = new Instructor("辅导员");
Handler collegeDean = new CollegeDean("院长");
Handler secretary = new Secretary("书记");
instructor.setNextHandler(collegeDean);
collegeDean.setNextHandler(secretary);
secretary.setNextHandler(instructor);//将链设置成环
instructor.process(7);
secretary.process(1);
}
}
public abstract class Handler {
protected String name;
protected Handler nextHandler;
public Handler(String name) {
this.name = name;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void process(int days);
}
public class Instructor extends Handler {
public Instructor(String name) {
super(name);
}
@Override
public void process(int days) {
if (days <= 0 || days > 30) {
System.out.printf("不允许请假%d%n", days);
} else if (days <= 3) {
System.out.printf("%s批准申请%d天假%n", name, days);
} else {
nextHandler.process(days);
}
}
}
public class CollegeDean extends Handler {
public CollegeDean(String name) {
super(name);
}
@Override
public void process(int days) {
if (days > 4 && days <= 7) {
System.out.printf("%s批准申请%d天假%n", name, days);
} else {
nextHandler.process(days);
}
}
}
public class Secretary extends Handler {
public Secretary(String name) {
super(name);
}
@Override
public void process(int days) {
if (days > 7 && days < 14) {
System.out.printf("%s批准申请%d天假%n", name, days);
} else if (nextHandler != null) {
nextHandler.process(days);
}
}
}