目录
总原则:开闭原则(Open Close Principle)
2、里氏替换原则(Liskov Substitution Principle)
3、依赖倒转原则(Dependence Inversion Principle)
4、接口隔离原则(Interface Segregation Principle)
5、迪米特法则(最少知道原则)(Demeter Principle)
6、合成复用原则(Composite Reuse Principle)
1. 工厂方法设计模式(Factory Method Pattern)
12.责任链设计模式(Chain of Responsibility Pattern)
14.解释器设计模式(Interpreter Pattern)
三、基于电商平台常用业务(订单、支付、优惠券等)创作的使用示例
一、简介
1.设计模式定义
设计模式是一组有用的解决方案,用于解决特定类型的软件设计问题。它们通常提供了一种抽象出来的方式,来表达应用程序中常见问题的解决方案,从而帮助开发者更有效地解决问题。设计模式的用途是帮助开发者解决软件设计问题,提高开发效率,降低开发成本,提高代码质量和可维护性,以及更好地管理和理解复杂的系统。设计模式的优点是可以提高代码可维护性,减少代码重复,提高开发效率,降低开发成本,提高代码质量和可维护性,以及更好地管理和理解复杂的系统。设计模式的缺点是可能会使代码变得复杂,也可能会过度设计。设计模式的出处是由GoF(Gang of Four)在1995年发表的著作“设计模式:可复用面向对象软件的基础”中提出。
2.设计模式的历史
设计模式可以追溯到1960年代,当时著名的软件工程师和设计师们开始研究如何提高软件开发的效率和可维护性。他们发现,应用一些重复出现的设计模式可以提高软件开发的效率,并极大地改善软件的可读性和可维护性。这些设计模式在1970年代末被称为“永恒的设计模式”,并在1995年由Erich Gamma,Richard Helm, Ralph Johnson和John Vlissides出版。他们的书,称为“设计模式:可复用面向对象软件的基础”,成为设计模式的代表作品,并且引发了关于设计模式的热烈讨论。此外,这本书还为软件开发人员提供了一套可复用的设计模式,以帮助他们更好地理解和实施设计模式
二、设计模式的六大原则
总原则:开闭原则(Open Close Principle)
实体应该对扩展开放,对修改关闭,即软件实体应尽量在不修改原有代码的情况下进行扩展。
应用时注意点是要充分利用抽象类和接口、多态等特性,将可变部分封装起来,提高系统的灵活性和可维护性。
1、单一职责原则
一个类应该只负责一项职责,不要存在多于一个的非本职责原因引起类的变更。简单来说就是类的职责要单一。
应用时注意点是要在设计时尽量把类的职责划分清楚,把功能模块化,提高系统的灵活性和可维护性。
2、里氏替换原则(Liskov Substitution Principle)
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
历史替换原则中,子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。
应用时注意点是在设计时应让父类和子类之间有一个共同的抽象层,以便子类可以重写父类的抽象方法,并在子类中实现这些抽象方法。
3、依赖倒转原则(Dependence Inversion Principle)
这个是开闭原则的基础,具体内容:面向接口编程,依赖于抽象而不依赖于具体。
应用时注意点是要在设计时以抽象为基础,尽量将细节层次降低,使系统可以更灵活地应对变化。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。
4、接口隔离原则(Interface Segregation Principle)
每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。简单地说使用多个专门的接口,而不使用单一的总接口。
应用时注意点是要把接口进行分解,使用多个小接口,以便更好地实现功能的模块化管理,提高系统的灵活性和可维护性。
5、迪米特法则(最少知道原则)(Demeter Principle)
就是说:一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。
最少知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。
应用时注意点是要尽量减少类与类之间的耦合,提高系统的灵活性和可维护性。
6、合成复用原则(Composite Reuse Principle)
指尽量使用组合/聚合的方式,而不是使用继承关系来达到复用的目的。
应用时注意点是要尽量使用组合/聚合的方式,使用继承可能带来的耦合性太强,从而影响系统的灵活性和可维护性。
二、设计模式的分类
总体来说设计模式分为三大类:
创建型设计模式,共五种:工厂方法设计模式、抽象工厂设计模式、单例设计模式、建造者设计模式、原型设计模式。
结构型设计模式,共七种:适配器设计模式、装饰器设计模式、代理设计模式、外观设计模式、桥接设计模式、组合设计模式、享元设计模式。
行为型设计模式,共十一种:策略设计模式、模板方法设计模式、观察者设计模式、迭代子设计模式、责任链设计模式、命令设计模式、备忘录设计模式、状态设计模式、访问者设计模式、中介者设计模式、解释器设计模式。
1. 工厂方法设计模式(Factory Method Pattern)
定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
它的思想是:在工厂设计模式中,我们创建对象不是直接使用 new 关键字创建,而是将创建对象的行为委托给另一个类,也就是工厂类。把实例化的步骤抽象出来,让子类决定实例化哪一个类。
应用场景:当一个类不知道它所必须创建的对象的类的时候,或者根据不同条件创建不同实例时,可以使用工厂设计模式。
2. 抽象工厂设计模式(Abstract Factory Pattern)
抽象工厂设计模式是一种创建型设计模式,它提供一种方法创建一组相关的产品,而无需指定它们的具体类。
优点:具体产品类的实现细节完全隐藏,不需要关心创建细节;增加新的具体产品类只需要添加一个新的具体产品类和相应的具体工厂类,不会影响已有系统;符合“开放-封闭”原则。
缺点:增加新的产品类比较困难,需要修改抽象工厂和所有的具体工厂类。
3.单例设计模式(Singleton Pattern)
单例设计模式是一种常用的软件设计模式,指的是在一个类里面有一个私有构造函数和一个公开静态方法,这个方法返回对象的唯一实例。
单例设计模式的应用场景是:需要一个只能创建一个实例的类,如 配置类、日志类、计数器类等。
优点:降低内存开销;确保全局唯一;可以控制实例数量。
缺点:不支持继承;不灵活;与单一职责原则冲突。
4.建造者设计模式(Builder Pattern)
建造者设计模式是一种创建型设计模式,它使用抽象的建造者来构建一个复杂的对象。
它的思想是:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者设计模式的应用场景是:当创建一个复杂的对象时,可以使用建造者设计模式来将复杂对象的创建过程与它的表示进行分离,从而使得构建过程更加清晰。
优点:构建和表示分离;良好的封装性;可以构造复杂的对象。
缺点:难以控制产品的组成部分;产品的组成部分太多,可能会出现很多具体的建造者类。
5.原型设计模式
原型设计模式是一种创建型设计模式,它使用一个原型对象来创建新的对象。
它的思想是:通过复制一个已经存在的实例来创建新的实例,而不是通过new关键字来创建新的实例。
原型设计模式的应用场景是:当类的创建开销比较大或者构造函数中需要复杂操作时,原型设计模式可以派上用场。
优点:性能优良;简化创建过程;灵活性高。
缺点:配备克隆方法需要对类的功能进行较大的改造,这是非常有风险的改动;必须实现Cloneable接口;使用原型设计模式时,不能使用final类型。
6.适配器设计模式(Adapter Pattern)
适配器设计模式是一种结构型设计模式,它将一个类的接口转换成客户希望的另一个接口。
它的思想是:将一个类的接口转换成客户希望的另一个接口,从而使原本接口不兼容的类可以一起工作。
适配器设计模式的应用场景是:当你希望使用一个已经存在的类,但是它的接口与你的要求不匹配时,可以使用适配器设计模式来解决这个问题。
优点:提高了类的复用性;增加了类的透明度;灵活性高。
缺点:增加了系统的复杂度;增加系统的理解和设计难度。
7.装饰者设计模式(Decorator Pattern)
装饰者设计模式是一种结构型设计模式,它可以在不改变一个对象的结构的情况下,给对象增加一些新的功能。
它的思想是:将一个类的功能进行加强,但是不改变它的结构。
装饰者设计模式的应用场景是:当你希望给一个类增加新的功能,而且不希望改变它的结构时,可以使用装饰者设计模式。
8.外观设计模式(Facade Pattern)
外观设计模式是一种结构型设计模式,它可以为复杂的子系统提供简单的接口,以便客户端可以方便地访问子系统。
它的思想是为复杂的子系统提供简单的接口,以便客户端可以方便地访问子系统。它的应用了依赖倒置原则。
应用场景是需要为复杂的子系统提供简单接口的场景。
9.桥接设计模式(Bridge Pattern)
桥接设计模式是一种结构型设计模式,它可以将抽象和实现解耦,从而让它们可以独立变化。它应用了接口隔离原则。
应用场景是需要将抽象和实现解耦的场景。
10.代理设计模式(Proxy Pattern)
代理设计模式是一种结构型设计模式,它可以为另一个对象提供一个替身或代理,以控制对这个对象的访问。它应用了迪米特法则。
应用场景是需要为另一个对象提供一个替身或代理的场景。
11.组合设计模式(Composite Pattern)
组合设计模式是一种结构型设计模式,它可以将对象组合成树形结构,从而使客户端可以使用统一的接口来处理单个对象和组合对象。它的原则是合成复用原则。
应用场景是需要将对象组合成树形结构的场景。
12.责任链设计模式(Chain of Responsibility Pattern)
它是一种行为设计模式,它使得请求发送者可以不需要知道处理者是谁,将请求发送给一系列的处理者,最终有处理者处理它。
它的原则是尽量减少请求发送者和处理者之间的耦合,有助于提高系统的灵活性和可扩展性。
13.命令设计模式(Command Pattern)
命令设计模式是一种行为设计模式,它将请求封装成一个对象,以便使用不同的请求、队列或者日志来参数化其他对象。
它的原则是将请求从它的发出者和执行者分离开来,以便实现低耦合、高内聚的系统结构。
14.解释器设计模式(Interpreter Pattern)
解释器设计模式是一种行为设计模式,它使用语法规则来解释使用者输入的数据,从而实现程序的功能。
它的原则是通过使用简单的语法规则来解释数据,以便更容易地实现程序功能。
15.迭代器设计模式(Iterator Pattern)
迭代器设计模式是一种行为设计模式,它使用迭代器对象来遍历容器,从而实现对容器中的元素的遍历。
它的原则是,将容器中的元素与其遍历操作分离开来,以便实现低耦合、高内聚的系统结构。
16.中介者设计模式(Mediator Pattern)
中介者设计模式是一种行为设计模式,它使用中介者对象来封装一组对象之间的交互,从而使这些对象之间的耦合度降低,提高系统的灵活性和可扩展性。它的原则是通过使用中介者对象来封装对象之间的交互,以便降低耦合度和提高系统的可扩展性。
17.观察者设计模式(Observer Pattern)
观察者设计模式是一种行为设计模式,它使用观察者对象来观察主题对象,以便当主题对象发生变化时,观察者对象可以获得通知。
它的原则是通过使用观察者对象来观察主题对象,以便当主题对象发生变化时,观察者对象可以获得通知。
18.状态设计模式(State Pattern)
状态设计模式是一种行为设计模式,它使用状态对象来封装与状态有关的行为,以便使用不同的状态实现不同的行为。
它的原则是通过使用状态对象来封装与状态有关的行为,以便使用不同的状态实现不同的行为。
19.策略设计模式(Strategy Pattern)
策略设计模式是一种行为设计模式,它使用策略对象来封装可以互换的算法,以便使用不同的算法来解决不同的问题。
它的原则是通过使用策略对象来封装可以互换的算法,以便使用不同的算法来解决不同的问题。
20.模板方法设计模式(Template Pattern)
模板方法设计模式是一种行为设计模式,它使用模板方法来定义一个算法的基本结构,以便将一些具体的步骤延迟到子类中实现。它的原则是通过使用模板方法来定义算法的基本结构,以便将一些具体的步骤延迟到子类中实现。
21.备忘录设计模式(Memento Pattern)
备忘录设计模式是一种行为设计模式,它使用备忘录对象来存储对象的内部状态,以便在需要的时候对对象进行恢复。
它的原则是通过使用备忘录对象来存储对象的内部状态,以便在需要的时候对对象进行恢复。
22.访问者设计模式(Visitor Pattern)
访问者设计模式是一种行为设计模式,它使用访问者对象来访问某个对象,以便在不改变它的结构的情况下添加新的操作。
它的原则是通过使用访问者对象来访问某个对象,以便在不改变它的结构的情况下添加新的操作。
23.享元设计模式(Flyweight Pattern)
享元设计模式是一种用于性能优化的软件设计模式,通过共享对象来有效地支持大量细粒度的对象。
原理:享元设计模式通过共享技术实现相同或相似对象的重用。它通过为相似对象分配共享内存来节省内存,从而改善应用程序的性能。
优点:
1.可以极大提高应用程序的性能,提升应用程序的运行效率;
2.可以减少内存的使用量,提升应用程序的可扩展性;
3.可以提高应用程序的可维护性,减少对象的创建次数。
缺点:
1.实现享元设计模式需要分离出内部状态和外部状态,而识别内部状态需要充分的分析和编程实现;
2.在享元设计模式中,需要关联外部状态,这将增加复杂度;
3.使用享元设计模式会增加系统的维护复杂度,需要分离出内部状态和外部状态,而识别内部状态需要充分的分析和编程实现。
三、基于电商平台常用业务(订单、支付、优惠券等)创作的使用示例
//单例设计模式
/*
单例设计模式的思想是将类的实例化控制在一个对象中,一个类只能有一个实例。
它的应用场景主要是在需要全局控制的情况下,例如在电商平台中,订单流程的控制,可以使用单例设计模式。
在多线程环境下,双重检查锁和 volatile 关键字的组合可以保证单例模式的线程安全性和正确性。
*/
public class OrderService {
private OrderService() {
}
//私有静态变量,保存实例
private volatile static OrderService instance;
//提供全局访问点
public static OrderService getInstance() {
if (instance == null) {
synchronized (OrderService.class) {
if (instance == null) {
instance = new OrderService();
}
}
}
return instance;
}
public void placeOrder(Order order) {
//...
}
}
//原型设计模式
/*
原型设计模式的思想是通过复制原型来创建一个新的对象。它的应用场景一般是在创建复杂对象时,可以先复制一个原型来进行一些初始化的工作,
然后在对其进行修改。在电商平台中,可以使用原型设计模式来创建订单对象,避免重复的初始化工作。
*/
public class Order implements Cloneable {
private String orderId;
private List<String> items;
public Order(String orderId, List<String> items) {
this.orderId = orderId;
this.items = items;
}
public Order clone() {
try {
return (Order) super.clone();
}
catch (CloneNotSupportedException e) {
e.printStackTrace(); return null;
}
}
}
//建造者设计模式
/*
建造者设计模式的思想是将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。它的应用场景一般是在创建复杂对象时,
可以将复杂对象的创建过程进行拆分,使得创建过程更加清晰。在电商平台中,可以使用建造者设计模式来创建订单对象,将复杂的构建过程分解成
几个步骤,从而使得创建过程更加清晰。
*/
public class OrderBuilder {
private String orderId;
private List<String> items;
public OrderBuilder setOrderId(String orderId) {
this.orderId = orderId;
return this;
}
public OrderBuilder setItems(List<String> items) {
this.items = items;
return this;
}
public Order build() {
return new Order(orderId, items);
}
}
//适配器设计模式
/*
适配器设计模式的思想是将一个类的接口转换成客户希望的另外一个接口。它的应用场景一般是在原有的类接口不符合客户需求的时候,
可以使用适配器设计模式来实现接口的转换。在电商平台中,可以使用适配器设计模式来转换订单对象的接口,使得订单对象更加符合客户的需求。
*/
public class OrderAdapter {
private Order order;
public OrderAdapter(Order order) {
this.order = order;
}
public String getOrderId() {
return order.getOrderId();
}
public List<String> getItems() {
return order.getItems();
}
}
//装饰者设计模式
/*
装饰者设计模式的思想是动态地将责任附加到对象上。它的应用场景一般是在原有类不满足客户需求时,可以在不改变原有类的基础上通过
装饰者设计模式来动态地增加新的功能。在电商平台中,可以使用装饰者设计模式来为订单对象增加新的功能,比如折扣功能,而不改变原有的订单对象。
*/
public class OrderDecorator {
private Order order;
public OrderDecorator(Order order) {
this.order = order;
}
public void setDiscount(double discount) {
order.setDiscount(discount);
}
public double getDiscount() {
return order.getDiscount();
}
}
//外观设计模式
/*
外观设计模式的思想是为子系统中的一组接口提供一个一致的界面,从而使子系统更加容易使用。它的应用场景一般是在复杂的系统中,可以使用外观设计模式
来简化系统的接口,从而使系统更加容易使用。在电商平台中,可以使用外观设计模式来简化订单系统的接口,使得订单系统更加容易使用。
*/
public class OrderFacade {
private OrderService orderService;
private OrderBuilder orderBuilder;
private OrderAdapter orderAdapter;
private OrderDecorator orderDecorator;
public OrderFacade() {
orderService = OrderService.getInstance();
orderBuilder = new OrderBuilder();
orderAdapter = new OrderAdapter();
orderDecorator = new OrderDecorator();
}
public void placeOrder(Order order) {
orderService.placeOrder(order);
}
public Order buildOrder(String orderId, List<String> items) {
return orderBuilder.setOrderId(orderId).setItems(items).build();
}
public OrderAdapter getOrderAdapter(Order order) {
return new OrderAdapter(order);
}
public OrderDecorator getOrderDecorator(Order order) {
return new OrderDecorator(order); }
}
//桥接设计模式
/*
桥接设计模式的思想是将抽象和实现分离,使它们可以独立变化。它的应用场景一般是在多个变化维度存在时,可以使用桥接设计模式来将抽象和实现分离,
从而使抽象和实现可以独立变化。在电商平台中,可以使用桥接设计模式来创建购物车对象,将购物车的抽象和实现分离,从而使得购物车的抽象和实
现可以独立变化。
*/
public abstract class Cart {
protected CartImplementor implementor;
public Cart(CartImplementor implementor) {
this.implementor = implementor;
}
public abstract void addItem(String item);
public abstract void removeItem(String item);
public abstract List<String> getItems();
}
//代理设计模式
/*
代理设计模式的思想是为其他对象提供一种代理以控制对这个对象的访问。它的应用场景一般是在访问某个对象时,可以使用代理设计模式来控制对这个对象的访问。
在电商平台中,可以使用代理设计模式来访问购物车对象,从而控制对购物车的访问。
*/
public class CartProxy implements Cart {
private Cart cart;
public CartProxy(Cart cart) {
this.cart = cart;
}
@Override
public void addItem(String item) {
cart.addItem(item);
}
@Override
public void removeItem(String item) {
cart.removeItem(item);
}
@Override
public List<String> getItems() {
return cart.getItems();
}
}
//组合设计模式
/*
组合设计模式的思想是将对象组合成树形结构,以表示部分-整体的层次结构。它的应用场景一般是在树形结构中,可以使用组合设计模式来将对象组合成树形结构,
从而表示部分-整体的层次结构。在电商平台中,可以使用组合设计模式来组织购物车对象,将购物车的对象组合成树形结构,从而表示部分-整体的层次结构。
*/
public class CartComposite extends CartComponent {
private List<CartComponent> components = new ArrayList<>();
@Override
public void add(CartComponent component) {
components.add(component);
}
@Override
public void remove(CartComponent component) {
components.remove(component);
}
@Override
public int getTotalPrice() {
int totalPrice = 0;
for (CartComponent component : components) {
totalPrice += component.getTotalPrice();
}
return totalPrice;
}
}
//责任链设计模式
/*
责任链设计模式的思想是将请求的处理者分开,每个处理者对请求做出响应,从而形成一条链,每个处理者都可以决定是否将请求传递给下一个处理者。
它的应用场景一般是在多种处理方法存在时,可以使用责任链设计模式来将请求的处理者分开,从而使得处理者之间形成一条链。在电商平台中,
可以使用责任链设计模式来处理购物车对象,将购物车的处理者分开,从而使得处理者之间形成一条链。
*/
public abstract class CartHandler {
protected CartHandler nextHandler;
public void setNextHandler(CartHandler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handle(Cart cart);
}
//命令设计模式
/*
命令设计模式的思想是将请求封装成一个对象,以便使用不同的请求、队列或者日志来参数化其他对象。它的应用场景一般是在请求不同时,
可以使用命令设计模式来将请求封装成对象,从而使用不同的请求参数化其他对象。在电商平台中,可以使用命令设计模式来执行购物车对象的操作,
将购物车的操作封装成对象,从而使用不同的请求参数化其他对象。
*/
public interface Command {
void execute(Cart cart);
}
public class AddItemCommand implements Command {
private String item;
public AddItemCommand(String item) {
this.item = item;
}
@Override
public void execute(Cart cart) {
cart.addItem(item);
}
}
//解释器设计模式
/*解释器设计模式的思想是为一个特定的上下文定义一个语言,并定义该语言的文法,然后使用该文法来解释语言中的句子。它的应用场景一般是在特定上下文中,可以使用解释器设计模式来定义一种语言,并使用该语言的文法来解释句子。在电商平台中,可以使用解释器设计模式来解释购物车对象的操作,定义一种语言,来描述购物车的操作,然后使用该语言的文法来解释句子,从而完成购物车的操作。
*/
public class CartExpressionParser {
public void parse(String expression, Cart cart) {
String[] tokens = expression.split(" ");
for (String token : tokens) {
if (token.equals("add")) {
String item = tokens[1];
cart.addItem(item);
}
else if (token.equals("remove")) {
String item = tokens[1];
cart.removeItem(item);
}
}
}
}
//迭代器设计模式
/*
迭代器设计模式的思想是提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。它的应用场景一般是在聚合对象中,
可以使用迭代器设计模式来提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。在电商平台中,可以使用迭代器
设计模式来遍历支付对象,提供一种方法顺序访问一个支付对象中的各个元素,而又不暴露该对象的内部表示。
*/
public interface Iterator {
boolean hasNext();
Object next();
}
public class PaymentIterator implements Iterator {
private Payment[] payments;
private int index;
public PaymentIterator(Payment[] payments) {
this.payments = payments;
}
@Override
public boolean hasNext() {
if (index >= payments.length || payments[index] == null) {
return false;
} else {
return true;
}
}
@Override
public Object next() {
Payment payment = payments[index];
index++;
return payment;
}
}
//中介者设计模式
/*
中介者设计模式的思想是用一个中介对象来封装一系列对象之间的交互,使各对象之间不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
它的应用场景一般是在多个对象之间存在复杂的引用关系时,可以使用中介者设计模式来封装这些复杂的引用关系,使各对象之间不需要显式地相互引用,
从而使其耦合松散。在电商平台中,可以使用中介者设计模式来封装支付对象之间的交互,使支付对象之间不需要显式地相互引用,从而使其耦合松散。
*/
public class Mediator {
private List<Payment> payments;
public Mediator(List<Payment> payments) {
this.payments = payments;
}
public void makePayment(Payment payment) {
payments.forEach(p -> {if (p != payment) {p.receivePayment(payment);}});
}
}
//观察者设计模式
/*
观察者设计模式的思想是定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。它的应用场景一般是在
对象间存在一对多的依赖关系时,可以使用观察者设计模式来定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知
并自动更新。在电商平台中,可以使用观察者设计模式来定义支付对象之间的一对多的依赖关系,使得每当一个支付对象改变状态,则所有依赖于它的支付对象都会得
到通知并自动更新。
*/
public interface Observer {
void update(Payment payment);
}
public class PaymentSubject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(Payment payment) {
for (Observer observer : observers) {
observer.update(payment);
}
}
}
//状态设计模式
/*
状态设计模式的思想是允许一个对象在其内部状态改变时改变它的行为,这个对象看起来就像是改变了它的类。它的应用场景一般是在一个对象的行为取决于它的状态,
可以使用状态设计模式来允许一个对象在其内部状态改变时改变它的行为,这个对象看起来就像是改变了它的类。在电商平台中,可以使用状态设计模式来允许支付对象在
其内部状态改变时改变它的行为,这个支付对象看起来就像是改变了它的类。
*/
public interface PaymentState {
void doAction(PaymentContext context);
}
public class PaymentContext {
private PaymentState paymentState;
public PaymentContext() {
paymentState = null;
}
public void setState(PaymentState state) {
this.paymentState = state;
}
public PaymentState getState() {
return paymentState;
}
public void doAction() {
paymentState.doAction(this);
}
}
//策略设计模式
/*
策略设计模式的思想是定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。它的应用场景一般是在多个类只有在算法或行为上稍有不同的情况下,
可以使用策略设计模式来定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。在电商平台中,可以使用策略设计模式来定义支付算法,把它们一个个
封装起来,并且使它们可以相互替换。
*/
public interface PaymentStrategy {
void pay(int amount);
}
public class CreditCardStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public CreditCardStrategy(String name, String cardNumber, String cvv, String dateOfExpiry) {
this.name = name;
this.cardNumber = cardNumber;
this.cvv = cvv;
this.dateOfExpiry = dateOfExpiry;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid with credit/debit card");
}
}
//模板方法设计模式
/*模板方法设计模式的思想是定义一个操作中的算法的骨架,而将一些步骤延迟到子类中实现。它的应用场景一般是在一次性实现一个算法的不变部分,并将可变部分留给
子类去实现时,可以使用模板方法设计模式来定义一个操作中的算法的骨架,而将一些步骤延迟到子类中实现。在电商平台中,可以使用模板方法设计模式来定义支付操作的算
法的骨架,而将一些步骤延迟到子类中实现。
*/
public abstract class PaymentTemplate {
protected abstract void doPayment();
public void payment() {
doPayment();
}
}
public class CreditCardPayment extends PaymentTemplate {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public CreditCardPayment(String name, String cardNumber, String cvv, String dateOfExpiry) {
this.name = name;
this.cardNumber = cardNumber;
this.cvv = cvv; this.dateOfExpiry = dateOfExpiry;
}
@Override
protected void doPayment() {
System.out.println("Paid with credit/debit card");
}
}
//备忘录设计模式
/*
备忘录设计模式的思想原则是:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到
原先保存的状态。应用场景:备忘录设计模式可以用于撤销操作等场景,比如电商平台的优惠券业务,可以使用备忘录设计模式来记录优惠券使用的状态,以便在需要撤销
操作时可以将优惠券状态恢复。 以电商平台的优惠券业务为例,具体的java代码可以参考如下:
*/
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
public class CouponService {
private Memento memento;
// 记录当前优惠券状态
public void saveMemento(Memento memento) {
this.memento = memento;
}
// 恢复优惠券使用状态
public void restoreMemento(Memento memento) {
this.memento = memento;
}
}
//访问者设计模式
/*
封装一些作用于某种数据结构的元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新操作。
应用场景:访问者设计模式适用于数据结构相对稳定的系统,把数据结构和算法解耦,可以较好的应对变化。比如电商平台的优惠券业务,
可以通过访问者设计模式对优惠券进行统一管理,根据不同的优惠券类型采用不同的操作。以电商平台的优惠券业务为例,具体的java代码可以参考如下:
*/
public class CouponVisitor {
public void visit(DiscountCoupon coupon) {
// do something
}
public void visit(CashCoupon coupon) {
// do something
}
}
//解释器设计模式
/*
为特定的语言创建一个解释器,用来解释该语言中的句子。
应用场景:解释器设计模式适用于语言文法比较简单的情况,比如电商平台的优惠券业务,可以通过解释器设计模式
来解析优惠券的使用规则,比如满多少金额可用等。以电商平台的优惠券业务为例,具体的java代码可以参考如下:
public abstract class AbstractExpression {
public abstract boolean interpret(String context);
}
public class TerminalExpression extends AbstractExpression {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
@Override
public boolean interpret(String context) {
if (context.contains(data)) {
return true;
} return false;
}
}
//调停者设计模式
/*
用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用,从而使耦合松散,而且可以独立的改变它们之间的交互。
应用场景:调停者设计模式适用于多个对象之间紧密耦合的情况,比如电商平台的优惠券业务,可以通过调停者设计模式来调节优惠券发放、使用、核销等各个环节之间的关系
,以便达到高效的运营管理。以电商平台的优惠券业务为例,具体的java代码可以参考如下:
*/
public class CouponMediator {
private List<CouponUser> users;
public CouponMediator() {
this.users = new ArrayList<>();
}
public void addUser(CouponUser user) {
this.users.add(user);
}
public void distributeCoupon(Coupon coupon) {
for (CouponUser user : users) {
user.receiveCoupon(coupon);
}
}
public void redeemCoupon(Coupon coupon) {
for (CouponUser user : users) {
user.redeemCoupon(coupon);
}
}
}