常用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() {
}
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)
}
}
}
//观察者模式
//状态模式
//策略模式
//模板方法模式
备忘录模式
//访问者模式
/*