常用23种设计模式Java经典实现(使用常用电商业务订单、购物车,商户,支付,优惠券为例)
//工厂方法设计模式(Factory Method Pattern)
定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
它的思想是:在工厂设计模式中,我们创建对象不是直接使用 new 关键字创建,而是将创建对象的行为委托给另一个类,也就是工厂类。把实例化的步骤抽象出来,让子类决定实例化哪一个类。 应用场景:当一个类不知道它所必须创建的对象的类的时候,或者根据不同条件创建不同实例时,可以使用工厂设计模式。
在GOF出版的《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
//1.简单工厂Simple Factory
//抽象工厂类
public abstract class CouponFactory {
public abstract Coupon createCoupon(String couponType);
}
//具体工厂类
public class ConcreteFactory extends CouponFactory {
@Override
public Coupon createCoupon(String couponType) {
switch (couponType) {
case "discount":
return new DiscountCoupon();
case "cashback":
return new CashBackCoupon();
default:
return null;
}
}
}
//抽象产品类
public abstract class Coupon
{
public abstract void printCouponInfo();
}
//具体产品类
public class DiscountCoupon extends Coupon {
@Override public void printCouponInfo() {
System.out.println("This is a discount coupon!");
}
}
public class CashBackCoupon extends Coupon {
@Override
public void printCouponInfo() { System.out.println("This is a cash back coupon!");
}
}
//客户端使用
public class Client {
public static void main(String[] args) {
CouponFactory couponFactory = new ConcreteFactory();
Coupon discountCoupon = couponFactory.createCoupon("discount");
discountCoupon.printCouponInfo();
Coupon cashbackCoupon = couponFactory.createCoupon("cashback");
cashbackCoupon.printCouponInfo();
}
}
1.2工厂方法模式(Factory Method)
//定义工厂方法模式抽象工厂类
public abstract class PaymentFactory {
public abstract Payment createPayment();
}
//定义工厂方法模式具体工厂类
public class CreditCardPaymentFactory extends PaymentFactory {
@Override
public Payment createPayment() {
return new CreditCardPayment();
}
}
//工厂方法模式客户端使用
public class Client {
public static void main(String[] args) {
PaymentFactory factory = new CreditCardPaymentFactory();
Payment payment = factory.createPayment();
payment.process();
}
}
//抽象工厂模式(Abstract Factory Pattern)
/*
以下是一个基于优惠券及活动业务的 Abstract Factory 的 Java 示例代码,在这个示例中,我们定义了抽象工厂类 AbstractCouponFactory
,其中包含了创建优惠券和活动的抽象方法 createCoupon()
和 createPromotion()
。然后,我们定义了具体的优惠券类 Coupon
和活动类 Promotion
,并实现了它们的具体行为。在 MotherAndBabyCouponFactory
工厂类中,我们实现了 createCoupon()
和 createPromotion()
方法,分别返回了 NewUserCoupon
类型的优惠券和 DoubleElevenPromotion
类型的活动。在客户端代码中,我们通过 MotherAndBabyCouponFactory
工厂类创建了优惠券和活动,并调用它们的方法进行使用和启动。 我们通过抽象工厂模式实现了优惠券和活动的创建,使得客户端代码与具体实现解耦,更加灵活。
*/
/** * 抽象工厂类 */ public abstract class AbstractCouponFactory { /** * 创建优惠券 */ public abstract Coupon createCoupon(); /** * 创建活动 */ public abstract Promotion createPromotion(); } /** * 优惠券类 */ public abstract class Coupon { public abstract void useCoupon(); } /** * 新用户优惠券 */ public class NewUserCoupon extends Coupon { public void useCoupon() { System.out.println("使用新用户优惠券"); } } /** * 活动类 */ public abstract class Promotion { public abstract void startPromotion(); } /** * 双十一活动 */ public class DoubleElevenPromotion extends Promotion { public void startPromotion() { System.out.println("开始双十一活动"); } } /** * 母婴类优惠券工厂 */ public class MotherAndBabyCouponFactory extends AbstractCouponFactory { public Coupon createCoupon() { return new NewUserCoupon(); } public Promotion createPromotion() { return new DoubleElevenPromotion(); } } /** * 客户端代码 */ public class Client { public static void main(String[] args) { AbstractCouponFactory factory = new MotherAndBabyCouponFactory(); Coupon coupon = factory.createCoupon(); Promotion promotion = factory.createPromotion(); coupon.useCoupon(); promotion.startPromotion(); } }
//单例模式
/*
单例模式的思想是将类的实例化控制在一个对象中,一个类只能有一个实例。
它的应用场景主要是在需要全局控制的情况下,例如在电商平台中,订单流程的控制,可以使用单例模式。
在下面的代码中,使用了双重检查锁机制来保证线程安全。使用 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 Mediator(List<Payment> payments) { this.payments = payments; }
public void makePayment(Payment payment) {
// 遍历所有Payment对象 for (Payment p : payments) {
// 排除当前Payment对象 if (p != payment) {
// 将支付信息传递给其他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);
}
}
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2009-04-22,如有侵权请联系 cloudcommunity@tencent 删除设计模式java电商public对象
发布评论