简介
本篇将使用大白话加自己的理解详细介绍23种设计模式
什么是设计模式
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。简单说:
- 模式:在某些场景下,针对某类问题的某种通用的解决方案
- 场景:项目所在的环境
- 问题:约束条件,项目目标等
- 解决方案:通用、可复用的设计,解决约束达到目标
设计模式的三个分类
- 创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。
- 结构型模式:把类或对象结合在一起形成一个更大的结构。
- 行为型模式:类和对象如何交互,及划分责任和算法。
各分类中模式的关键点
创建型模式
- 单例模式:某个类只能有一个实例,提供一个全局的访问点。
- 简单工厂:一个工厂类根据传入的参量决定创建出那一种产品类的实例。
- 工厂方法:定义一个创建对象的接口,让子类决定实例化那个类。
- 抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。
- 建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。
- 原型模式:通过复制现有的实例来创建新的实例。
结构型模式
- 适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。
- 组合模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构。
- 装饰模式:动态的给对象添加新的功能。
- 代理模式:为其他对象提供一个代理以便控制这个对象的访问。
- 亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。
- 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。
- 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。
行为型模式
- 模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。
- 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。
- 策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。
- 状态模式:允许一个对象在其对象内部状态改变时改变它的行为。
- 观察者模式:对象间的一对多的依赖关系。
- 备忘录模式:在不破坏封装的前提下,保持对象的内部状态。
- 中介者模式:用一个中介对象来封装一系列的对象交互。
- 命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。
- 访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素的新功能。
- 责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。
- 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。
详解
创建型模式
创建型模式的作用就是创建对象,说到创建一个对象,最熟悉的就是 new 一个对象,然后 set 相关属性。但是,在很多场景下,我们需要给客户端提供更加友好的创建对象的方式,尤其是那种我们定义了类,但是需要提供给其他开发者用的时候。
简单工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
interface Car{public void whoAmI();}
class BMWCar implements Car { @Override public void whoAmI() { System.out.println("I`m BWM");} }
class BenzCar implements Car{ @Override public void whoAmI() { System.out.println("I`m Benz"); } }
public class SimpleFactory { public static Car create(String name){ if("Benz".equals(name)){ return new BenzCar(); } if("BWM".equals(name)){ return new BMWCar(); } throw new InvalidParameterException("参数异常"); }
public static void main(String[] args) { SimpleFactory.create("Benz").whoAmI(); SimpleFactory.create("BWM").whoAmI(); } }
|
工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
public class Factory { public static void main(String[] args) { CarFactory carFactory1 = new ChineseFactory(); CarFactory carFactory2 = new GermanyFactory(); carFactory1.create("Benz").whoAmI(); carFactory1.create("BWM").whoAmI(); carFactory2.create("Benz").whoAmI(); carFactory2.create("BWM").whoAmI(); } }
class ChineseBenz implements Car{ @Override public void whoAmI() { System.out.println("I`m Chinese Benz"); } }
class GermanyBenz implements Car{ @Override public void whoAmI() { System.out.println("I`m Germany Benz"); } }
class ChineseBWM implements Car{ @Override public void whoAmI() { System.out.println("I`m Chinese BWM"); } }
class GermanyBWM implements Car{ @Override public void whoAmI() { System.out.println("I`m Germany BWM"); } }
interface CarFactory{ public Car create(String name); }
class ChineseFactory implements CarFactory{ @Override public Car create(String name) { if("Benz".equals(name)){ return new ChineseBenz(); } if("BWM".equals(name)){ return new ChineseBWM(); } throw new InvalidParameterException("参数异常"); } }
class GermanyFactory implements CarFactory{ @Override public Car create(String name) { if("Benz".equals(name)){ return new GermanyBenz(); } if("BWM".equals(name)){ return new GermanyBWM(); } throw new InvalidParameterException("参数异常"); } }
|
抽象工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
public class AbstractFactory { public static void main(String[] args) { AssemblyCarFactory assemblyCarFactory = new BenzAssemblyCarFactory(); Engine engine = assemblyCarFactory.createEngine(); Frame frame = assemblyCarFactory.createFrame(); Tire tire = assemblyCarFactory.createTire(); AssemblyCar benzAssemblyCar = new AssemblyCar(engine, frame, tire); System.out.println(benzAssemblyCar);
} }
class BenzAssemblyCarFactory implements AssemblyCarFactory{ public Tire createTire(){ return new BenzTire(); } public Frame createFrame(){ return new BenzFrame(); } public Engine createEngine(){ return new BenzEngine(); } }
interface AssemblyCarFactory{ public Tire createTire(); public Frame createFrame(); public Engine createEngine(); }
@Data @AllArgsConstructor class Tire{ private String name; } class BenzTire extends Tire{ public BenzTire() { super("Benz Tire"); } }
@Data @AllArgsConstructor class Frame{ private String name; } class BenzFrame extends Frame{ public BenzFrame() { super("Benz Frame"); } }
@Data @ToString @AllArgsConstructor class Engine{ private String name; } class BenzEngine extends Engine{ public BenzEngine() { super("Benz Engine"); } } @Data @AllArgsConstructor @ToString class AssemblyCar { private Engine engine; private Frame frame; private Tire tire; }
|
单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
public class Singleton { public static void main(String[] args) { Singleton1.getInstance().say(); Singleton2.getInstance().say(); Singleton3.getInstance().say(); } }
class Singleton1{ private Singleton1() {}; private static Singleton1 instance = new Singleton1(); public static Singleton1 getInstance() { return instance; } public void say(){ System.out.println("饿汉模式"); }
public static String getData(String mode) {return mode;} }
class Singleton2{ private Singleton2() {}; private static volatile Singleton2 instance = null; public static Singleton2 getInstance() { if (instance == null) { synchronized (Singleton2.class) { if (instance == null) { instance = new Singleton2(); } } } return instance; } public void say(){ System.out.println("饱汉模式(线程安全)"); } }
class Singleton3 { private Singleton3() {} private static class Holder { private static Singleton3 instance = new Singleton3(); } public static Singleton3 getInstance() { return Holder.instance; } public void say(){ System.out.println("嵌套类模式"); } }
|
建造者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
public class Builder { public static void main(String[] args) { User user = User.builder().name("张三").password("123456").build(); System.out.println(user); User1 user1 = User1.builder().name("李四").password("123").build(); System.out.println(user1); } } @Data @ToString class User{ private String name; private String password; private User(String name,String password){ this.name = name; this.password = password; } static class UserBuilder { private String name; private String password; public UserBuilder name(String name){ this.name = name; return this; } public UserBuilder password(String password){ this.password = password; return this; } public User build(){ if (name == null || password == null) { throw new RuntimeException("用户名和密码必填"); } return new User(name, password); } } public static UserBuilder builder() { return new UserBuilder(); }
}
@Data @ToString @lombok.Builder class User1 { private String name; private String password;
private User1(String name, String password) { this.name = name; this.password = password; } }
|
原型模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
public class Prototype { public static void main(String[] args) { CloneableUser user5 = CloneableUser.builder().name("王五").password("000").build(); CloneableUser user6 = user5.clone(); System.out.println(user5); user5.setName("王五-1"); System.out.println(user5); System.out.println(user6); } } @Data @Builder @AllArgsConstructor class CloneableUser { private String name; private String password; @Override protected CloneableUser clone() { return new CloneableUser(this.name,this.password); } }
|
创建型模式总结
创建型模式总体上比较简单,它们的作用就是为了产生实例对象,算是各种工作的第一步了,因为我们写的是面向对象的代码,所以我们第一步当然是需要创建一个对象了。简单工厂模式最简单;工厂模式在简单工厂模式的基础上增加了选择工厂的维度,需要第一步选择合适的工厂;抽象工厂模式有产品族的概念,如果各个产品是存在兼容性问题的,就要用抽象工厂模式。单例模式就不说了,为了保证全局使用的是同一对象,一方面是安全性考虑,一方面是为了节省资源;建造者模式专门对付属性很多的那种类,为了让代码更优美,也可以更好的做变量检查;原型模式用得最少,了解和 Object 类中的 clone() 方法相关的知识即可。
结构型模式
这节介绍的结构型模式旨在通过改变代码结构来达到解耦的目的,使得我们的代码容易维护和扩展。
代理模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
public class ProxyMode { public static void main(String[] args) { SayHelloProxy sayHelloProxy = new SayHelloProxy(); sayHelloProxy.say(); } } interface ISayHelloService{ public void say(); } class SayHelloServiceImpl implements ISayHelloService{ @Override public void say() { System.out.println("Hello, I`m SayHelloServiceImpl!"); } }
class SayHelloProxy implements ISayHelloService{ private ISayHelloService sayHelloService = new SayHelloServiceImpl(); @Override public void say() { System.out.println("开始SayHello"); sayHelloService.say(); System.out.println("结束SayHello"); } }
|
适配器模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
public class AdapterMode { public static void main(String[] args) { new DefaultAdapter().func1(); } }
class DefaultAdapter extends TopInterfaceAdapter{ @Override public void func1() { super.func1(); System.out.println("I`m Func1"); } } interface TopInterface{ void func1(); void func2(); void func3(); }
class TopInterfaceAdapter implements TopInterface{ @Override public void func1() { System.out.println("I`m Adapter Func1"); } @Override public void func2() { } @Override public void func3() { } }
class ObjectAdapter{ public static void main(String[] args) { Cock cock = new WildCock(); Duck duck = new CockAdapter(cock); duck.fly(); duck.quack(); } } interface Duck { public void quack(); public void fly(); } interface Cock { public void gobble(); public void fly(); }
class WildCock implements Cock { public void gobble() { System.out.println("咕咕叫"); } public void fly() { System.out.println("鸡也会飞哦"); } }
@AllArgsConstructor class CockAdapter implements Duck{ Cock cock; @Override public void quack() { cock.gobble(); }
@Override public void fly() { cock.fly(); } }
interface Target{ void func1(); void func2(); void func3(); } class SomeThing{ public void func1(){ System.out.println("I`m SomeThing Func1"); } public void func2(){ System.out.println("I`m SomeThing Func2"); } } class TargetAdapter extends SomeThing implements Target{ @Override public void func3() { System.out.println("I`m TargetAdapter func3"); } } class ClassAdapter{ public static void main(String[] args) { Target target = new TargetAdapter(); target.func1(); target.func2(); target.func3(); } }
|
总结:
- 类适配和对象适配的异同:
- 一个采用继承,一个采用组合;
- 类适配属于静态实现,对象适配属于组合的动态实现,对象适配需要多实例化一个对象。
- 总体来说,对象适配用得比较多。
- 适配器模式和代理模式的异同:
- 比较这两种模式,其实是比较对象适配器模式和代理模式,在代码结构上,它们很相似,都需要一个具体的实现类的实例。但是它们的目的不一样,代理模式做的是增强原方法的活;适配器做的是适配的活,为的是提供“把鸡包装成鸭,然后当做鸭来使用”,而鸡和鸭它们之间原本没有继承关系。

桥接模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| package top.kthirty.structural;
public class BridgeMode { public static void main(String[] args) { Shape blueCircle = new Circle(10, new BluePen()); blueCircle.draw(); Shape redCircle = new Circle(10, new RedPen()); redCircle.draw(); Shape blueRectangle = new Rectangle(1,2, new BluePen()); blueRectangle.draw(); Shape redRectangle = new Rectangle(1,2, new RedPen()); redRectangle.draw(); } }
interface DrawAPI { public void draw(int radius, int x, int y); }
class RedPen implements DrawAPI { @Override public void draw(int radius, int x, int y) { System.out.println("用红色笔画图,radius:" + radius + ", x:" + x + ", y:" + y); } }
class BluePen implements DrawAPI { @Override public void draw(int radius, int x, int y) { System.out.println("用蓝色笔画图,radius:" + radius + ", x:" + x + ", y:" + y); } }
abstract class Shape { protected DrawAPI drawAPI; protected Shape(DrawAPI drawAPI) { this.drawAPI = drawAPI; } public abstract void draw(); }
class Circle extends Shape { private int radius; public Circle(int radius, DrawAPI drawAPI) { super(drawAPI); this.radius = radius; } public void draw() { drawAPI.draw(radius, 0, 0); } }
class Rectangle extends Shape { private int x; private int y;
public Rectangle(int x, int y, DrawAPI drawAPI) { super(drawAPI); this.x = x; this.y = y; } public void draw() { drawAPI.draw(0, x, y); } }
|
装饰模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
public class DecorativeMode { public static void main(String[] args) { beverage = new Lemon(new RedTea()); System.out.println(beverage.getDescription()); System.out.println(beverage.cost()); } }
abstract class Beverage{ public abstract String getDescription(); public abstract double cost(); }
class RedTea extends Beverage{ @Override public String getDescription() { return "红茶"; } @Override public double cost() { return 10; } }
abstract class Condiment extends Beverage { }
@AllArgsConstructor class Lemon extends Condiment{ private Beverage beverage; @Override public String getDescription() { return beverage.getDescription()+"加柠檬"; } @Override public double cost() { return beverage.cost()+2; } }
|
门面模式(又叫外观模式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
public class FacadeMode { public static void main(String[] args) { ShapeMaker shapeMaker = new ShapeMaker(); shapeMaker.drawRedCircle(); shapeMaker.drawRedRectangle(); } }
class ShapeMaker{ private Shape redCircle; private Shape redRectangle; public ShapeMaker() { redCircle = new Circle(10,new RedPen()); redRectangle = new Rectangle(1,2,new RedPen()); } public void drawRedCircle(){ redCircle.draw(); } public void drawRedRectangle(){ redRectangle.draw(); } }
|
组合模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public class PortfolioMode { public static void main(String[] args) { Menu menu = new Menu("测试一", new ArrayList<>()).addChild(new Menu("测试二", new ArrayList<>())); System.out.println(menu); } } @Data @ToString @AllArgsConstructor class Menu{ private String name; private List<Menu> childMenus; public Menu addChild(Menu menu){ childMenus.add(menu); return this; } }
|
享元模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
public class FlyweightPattern { private static Map<String,Flyweight> pool= new HashMap<String,Flyweight>(); public static Flyweight getFlyweight(String subject){ Flyweight flyweight; if (pool.containsKey(subject)){ flyweight=pool.get(subject); }else { flyweight = new RealFlyweight(subject); pool.put(subject,flyweight); } return flyweight; } public static void main(String[] args) { System.out.println(pool.size()); getFlyweight("math"); System.out.println(pool.size()); getFlyweight("english"); System.out.println(pool.size()); getFlyweight("math"); System.out.println(pool.size()); } } abstract class Flyweight{ private String name; private String age; private final String subject; protected Flyweight(String subject) { this.subject = subject; } public abstract void exam(); public String getSubject() { return subject; } } class RealFlyweight extends Flyweight { @Override public void exam() { System.out.println(this.getSubject()+" is examing..."); } public RealFlyweight(String subject){ super(subject); } }
|
结构型模式总结
代理模式是做方法增强的,适配器模式是把鸡包装成鸭这种用来适配接口的,桥梁模式做到了很好的解耦,装饰模式从名字上就看得出来,适合于装饰类或者说是增强类的场景,门面模式的优点是客户端不需要关心实例化过程,只要调用需要的方法即可,组合模式用于描述具有层次结构的数据,享元模式是为了在特定的场景中缓存已经创建的对象,用于提高性能。
行为型模式
行为型模式关注的是各个类之间的相互作用,将职责划分清楚,使得我们的代码更加地清晰。
策略模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
public class StrategyPattern { public static void main(String[] args) { Payer payer = new Payer(); payer.setPay(new WechatPay()); payer.pay(1L,100D); } } interface IPay{ public void pay(Long userId,Double amount); } class WechatPay implements IPay{ @Override public void pay(Long userId, Double amount) { System.out.println(String.format("用户%s使用微信支付%s元",userId,amount)); } } class AliPay implements IPay{ @Override public void pay(Long userId, Double amount) { System.out.println(String.format("用户%s使用支付宝支付%s元",userId,amount)); } } @Data class Payer{ private IPay pay; public void pay(Long userId, Double amount){ this.pay.pay(userId, amount); } }
|
观察者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
public class ObserverPattern { public static void main(String[] args) { Order order = new Order(); order.setId(1L); order.setStatus("1"); order.attach(new OrderStatusChangeSendMailObserver()); order.attach(new OrderStatusChangeSendMsgObserver()); order.setStatus("2"); } } abstract class OrderStatusChangeObserver { protected Order order; public abstract void change(Order order,String beforeStatus,String afterStatus); } @ToString class Order{ private List<OrderStatusChangeObserver> orderStatusChangeObservers = new ArrayList<>(); private String status; private Long id; public void attach(OrderStatusChangeObserver orderStatusChangeObserver){ orderStatusChangeObservers.add(orderStatusChangeObserver); } public String getStatus() { return status; } public Long getId() { return id; } public void setStatus(String status){ String beforeStatus = this.status; this.status = status; orderStatusChangeObservers.forEach(o -> o.change(this,beforeStatus,status)); } public void setId(Long id){ this.id = id; } } class OrderStatusChangeSendMsgObserver extends OrderStatusChangeObserver{ @Override public void change(Order order, String beforeStatus, String afterStatus) { System.out.println(String.format("发送短信:订单%s状态变更,变更前状态%s,变更后状态%s",order.getId(),beforeStatus,afterStatus)); } } class OrderStatusChangeSendMailObserver extends OrderStatusChangeObserver{ @Override public void change(Order order, String beforeStatus, String afterStatus) { System.out.println(String.format("发送邮件:订单%s状态变更,变更前状态%s,变更后状态%s",order.getId(),beforeStatus,afterStatus)); } }
|
责任链模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
public class ResponsibilityChainPattern { public static void main(String[] args) { RuleHandler goodsCountValidRuleHandler = new GoodsCountValidRuleHandler(); goodsCountValidRuleHandler.setSuccessor(new UserAmountValidRuleHandler()); User user = new User(1L, 100D); Goods goods = new Goods(1L, 110D, 1L); goodsCountValidRuleHandler.apply(user,goods); } }
@Data @AllArgsConstructor class User{ private Long id; private Double amount; }
@Data @AllArgsConstructor class Goods{ private Long id; private Double price; private Long count; }
@Data abstract class RuleHandler { protected RuleHandler successor; public abstract void apply(User user,Goods goods); public void sendNext(User user,Goods goods){ if(successor != null){ successor.apply(user,goods); } } }
class GoodsCountValidRuleHandler extends RuleHandler{ @Override public void apply(User user, Goods goods) { if(goods.getCount()<=0){ throw new RuntimeException("库存不足"); } sendNext(user,goods); } }
class UserAmountValidRuleHandler extends RuleHandler{ @Override public void apply(User user, Goods goods) { if(user.getAmount() < goods.getPrice()){ throw new RuntimeException("余额不足"); } sendNext(user,goods); } }
|
模板方法模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
public class TemplateMethodPattern { public static void main(String[] args) { AbstractTemplate t = new ConcreteTemplate(); t.templateMethod(); } } abstract class AbstractTemplate{ public void templateMethod(){ init(); apply(); end(); } protected void init() { System.out.println("init 抽象层已经实现,子类也可以选择覆写"); } protected abstract void apply(); protected void end() {} } class ConcreteTemplate extends AbstractTemplate { public void apply() { System.out.println("子类实现抽象方法 apply"); } public void end() { System.out.println("我们可以把 method3 当做钩子方法来使用,需要的时候覆写就可以了"); } }
|
状态模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
public class StatePattern { public static void main(String[] args) { Context context = new Context(); context.setId(1L); StartState startState = new StartState(); startState.doAction(context); StopState stopState = new StopState(); stopState.doAction(context); } } @Data class Context { private Long id; private State state = null; } interface State { public void doAction(Context context); } class StartState implements State{ @Override public void doAction(Context context) { System.out.println(context.getId()+"Start State doAction"); } } class StopState implements State{ @Override public void doAction(Context context) { System.out.println(context.getId()+"Stop State doAction"); } }
|
行为型模式总结
行为型模式部分介绍了策略模式、观察者模式、责任链模式、模板方法模式和状态模式,其实,经典的行为型模式还包括备忘录模式、命令模式等,但是它们的使用场景比较有限,而且本文篇幅也挺大了,我就不进行介绍了。
总结
学习设计模式的目的是为了让我们的代码更加的优雅、易维护、易扩展。
- 创建型模式: 创建对象
- 结构型模式: 解耦,利于拓展维护
- 行为型模式: 拆分分工,单类只负责一种逻辑