什么是设计模式?
设计模式是软件开发过程中经常遇到的问题的通用解决方案。类似于前人总结的经验,遇到相似问题的时候有个参考。
设计模式七大基本原则?
- 单一职责:一个类应该只作一件事情。将功能分为小的独立的单元。
- 开放封闭原则:对扩展开放,对修改关闭。
- 里氏替换原则:任何一个父类出现的地方,都可以用子类替换,而不会导致错误或者异常。
- 依赖倒置:高层模块不应该依赖于底层,应该依赖于抽象,实现解耦。
- 接口隔离:一个类不应该强迫它的客户端依赖于它们不需要的方法,接口应该小而专注,不应该包含多余的方法。
责任链模式?
- 一种行为型设计模式,使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合。
- 请求沿着链传递,直到有对象处理为止。
- 分为三个角色:
- Handler:抽象处理者,定义了一个处理请求的接口或者抽象类,通常会包含一个指向链中下一个处理者的引用。
- ConcreteHandler:具体处理者,实现抽象处理者的处理方法,如果能处理就处理,不能就转发给下一个。
- client:客户端,创建处理链,并向链的第一个处理者对象提交请求。
- 工作流程:
- 客户端将请求发送给链上的第一个处理者对象
- 接收到请求后是否能处理
- 可以就处理
- 不可以就转发给链上的下一个处理者
- 过程重复
- 场景:
- 过滤器链
- 日志记录
- 异常处理
- 认证授权
- 优缺点:
- 降低耦合度
- 实际举例:
- 比如在线商店,用户下单的时候需要
- 检查订单信息是否完整
- 检查商品库存是否充足
- 检查用户余额是否充足
- 确认订单,更新商品库存和用户余额
- 比如在线商店,用户下单的时候需要
public interface OrderHandler{void handler(Order order);
}
public class CheckOrderHandler implements OrderHandler {private OrderHandler next;public CheckOrderHandler(OrderHandler next) {this.next = next;}@Overridepublic void hand1e(Order order) {
//检查订单信息是否完整if (order.isInfoComplete()) {
//如果订单信息完整,则将请求传递给下一个处理者next.handle(order);} else {
//如果订单信息不完整,则直接返回错误信息throw new RuntimeException("订 单信息不完整");}}public class CheckStockHandler implements OrderHandler {private OrderHandler next;public CheckStockHandler(OrderHandler next) {this.next = next;}@Overridepublic void hand1e(Order order) {
//检查商品库存是否充足.if (order.getStock() >= order.getQuantity()) {
//如果库存充足,则将请求传递给下一个处理者next.handle(order); } else {
//如果库存不足,则直接返回错误信息throw new RuntimeException(" 商品库存不足");}}}public class CheckBalanceHandler implements OrderHandler {private OrderHandler next;public CheckBalanceHandler(OrderHandler next) {this.next = next;}@Overridepublic void hand1e(Order order) {
//检查用户余额是否充足.if (order.getBalance() >= order.getAmount()) {
//如果余额充足,则将请求传递给下一个处理者.next.handle(order); } else {
//如果余额不足,则直接返回错误信息throw new RuntimeException("用户 余额不足");}}}public class ConfirmOrderHandler implements OrderHandler {@Overridepublic void handle(Order order) {
//确认订单,更新商品库存和用户余额order.confirm();}}
//客户端代码示例CheckOrderHandler checkOrderHandler = newCheckOrderHandler();CheckStockHandler checkStockHandler = new CheckStockHand1er();CheckBalanceHandler checkBalanceHandler = new CheckBalanceHandler();ConfirmOrderHandler confirmOrderHandler =newConfirmOrderHand1er();
//将处理器按照一定顺序组成责任链checkOrderHand1er.setNext(checkStockHandler);checkStockHand1er.setNext(checkBalanceHandler);checkBalanceHand1er.setNext(confirmOrderHandler);// 处理订单Order order = new Order();checkOrderHandler.handle(order);
工厂模式?
- 创建型设计模式主要创建对现象,而不暴露对象的逻辑给客户端。
- 简单工厂
-
简单工厂模式的角色包括三个:
-
抽象产品 角色
-
public abstract class Weapon {/*** 所有的武器都有攻击行为*/public abstract void attack(); }
-
具体产品角色
-
public class Tank extends Weapon{@Overridepublic void attack() {System.out.println("坦克开炮!");} }/*** 战斗机(具体产品角色)* @version 1.0* @className Fighter* @since 1.0**/ public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机投下原子弹!");} }/*** 匕首(具体产品角色)* @version 1.0* @className Dagger* @since 1.0**/ public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("砍他丫的!");} }
-
工厂类 角色
-
public class WeaponFactory {/*** 根据不同的武器类型生产武器* @param weaponType 武器类型* @return 武器对象*/public static Weapon get(String weaponType){if (weaponType == null || weaponType.trim().length() == 0) {return null;}Weapon weapon = null;if ("TANK".equals(weaponType)) {weapon = new Tank();} else if ("FIGHTER".equals(weaponType)) {weapon = new Fighter();} else if ("DAGGER".equals(weaponType)) {weapon = new Dagger();} else {throw new RuntimeException("不支持该武器!");}return weapon;} }
优点:不需要关注对象创建细节,要什么对象直接向工厂要就可以,初步实现了生产和消费的分离。缺点:工厂为上帝类,不能出问题;不符合OCP开闭原则,扩展时需要修改工厂类。
-
spring通过依赖注入和面向接口编程解决
-
-
- 工厂方法
-
工厂方法模式既保留了简单工厂模式的优点,同时又解决了简单工厂模式的缺点。
工厂方法模式的角色包括:
-
抽象工厂角色
-
/*** 武器工厂接口(抽象工厂角色)* @author 动力节点* @version 1.0* @className WeaponFactory* @since 1.0**/ public interface WeaponFactory {Weapon get(); }
-
具体工厂角色
-
/*** 具体工厂角色* @author 动力节点* @version 1.0* @className GunFactory* @since 1.0**/ public class GunFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Gun();} } package com.powernode.factory;/*** 具体工厂角色* @author 动力节点* @version 1.0* @className FighterFactory* @since 1.0**/ public class FighterFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Fighter();} }
-
抽象产品角色
-
/*** 武器类(抽象产品角色)* @author 动力节点* @version 1.0* @className Weapon* @since 1.0**/ public abstract class Weapon {/*** 所有武器都有攻击行为*/public abstract void attack(); }
-
具体产品角色
-
/*** 具体产品角色* @author 动力节点* @version 1.0* @className Gun* @since 1.0**/ public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");} } package com.powernode.factory;/*** 具体产品角色* @author 动力节点* @version 1.0* @className Fighter* @since 1.0**/ public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机发射核弹!");} }
扩展时增加一个产品+工厂,缺点:类爆炸
-
-
-
抽象工厂模式:
-
- 抽象工厂中包含4个角色:
-
抽象工厂角色
-
public abstract class AbstractFactory {public abstract Weapon getWeapon(String type);public abstract Fruit getFruit(String type); }
-
具体工厂角色
-
public class WeaponFactory extends AbstractFactory{public Weapon getWeapon(String type){if (type == null || type.trim().length() == 0) {return null;}if ("Gun".equals(type)) {return new Gun();} else if ("Dagger".equals(type)) {return new Dagger();} else {throw new RuntimeException("无法生产该武器");}}@Overridepublic Fruit getFruit(String type) {return null;} }public class FruitFactory extends AbstractFactory{@Overridepublic Weapon getWeapon(String type) {return null;}public Fruit getFruit(String type){if (type == null || type.trim().length() == 0) {return null;}if ("Orange".equals(type)) {return new Orange();} else if ("Apple".equals(type)) {return new Apple();} else {throw new RuntimeException("我家果园不产这种水果");}} }
-
抽象产品角色
-
具体产品角色
-
public abstract class Weapon {public abstract void attack(); } package com.powernode.product;public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");} }public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("砍丫的!");} }
优点:能保证一个工厂只使用一个类型的
-
缺点:不符合OCP、
-
-
- 抽象工厂中包含4个角色:
单例模式?
见另一篇
策略模式和模板设计模式?
- 策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法独立于使用它的客户而变化。
-
// 定义策略接口 public interface PaymentStrategy {void pay(int amount); }// 具体策略类:信用卡支付 public class CreditCardPaymentStrategy implements PaymentStrategy {private String cardNumber;public CreditCardPaymentStrategy(String cardNumber) {this.cardNumber = cardNumber;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);} }// 具体策略类:PayPal支付 public class PayPalPaymentStrategy implements PaymentStrategy {private String email;public PayPalPaymentStrategy(String email) {this.email = email;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using PayPal: " + email);} }// 环境类:使用策略 public class ShoppingCart {private PaymentStrategy paymentStrategy;public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void checkout(int amount) {paymentStrategy.pay(amount);} }// 客户端代码 public class Main {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart();// 使用信用卡支付cart.setPaymentStrategy(new CreditCardPaymentStrategy("1234-5678-9012-3456"));cart.checkout(100);// 使用PayPal支付cart.setPaymentStrategy(new PayPalPaymentStrategy("example@example.com"));cart.checkout(200);} }
- 模板方法模式:
- 模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
-
结合:// 抽象类,定义模板方法和抽象方法 public abstract class Game {// 模板方法public final void play() {initialize();startPlay();endPlay();}protected abstract void initialize();protected abstract void startPlay();protected abstract void endPlay(); }// 具体类:足球游戏 public class Football extends Game {@Overrideprotected void initialize() {System.out.println("Football Game Initialized! Start playing.");}@Overrideprotected void startPlay() {System.out.println("Football Game Started. Enjoy the game!");}@Overrideprotected void endPlay() {System.out.println("Football Game Finished!");} }// 具体类:篮球游戏 public class Basketball extends Game {@Overrideprotected void initialize() {System.out.println("Basketball Game Initialized! Start playing.");}@Overrideprotected void startPlay() {System.out.println("Basketball Game Started. Enjoy the game!");}@Overrideprotected void endPlay() {System.out.println("Basketball Game Finished!");} }// 客户端代码 public class Main {public static void main(String[] args) {Game game = new Football();game.play();game = new Basketball();game.play();} }
-
// 定义支付策略接口 public interface PaymentStrategy {void pay(int amount); }// 具体支付策略类:信用卡支付 public class CreditCardPaymentStrategy implements PaymentStrategy {private String cardNumber;public CreditCardPaymentStrategy(String cardNumber) {this.cardNumber = cardNumber;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);} }// 具体支付策略类:PayPal支付 public class PayPalPaymentStrategy implements PaymentStrategy {private String email;public PayPalPaymentStrategy(String email) {this.email = email;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using PayPal: " + email);} }
// 抽象类,定义支付流程的模板方法 public abstract class PaymentProcess {private PaymentStrategy paymentStrategy;public PaymentProcess(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}// 模板方法public final void processPayment(int amount) {selectItem();enterShippingDetails();if (confirmOrder()) {makePayment(amount);}sendReceipt();}protected void selectItem() {System.out.println("Item selected.");}protected void enterShippingDetails() {System.out.println("Shipping details entered.");}protected boolean confirmOrder() {System.out.println("Order confirmed.");return true;}protected void makePayment(int amount) {paymentStrategy.pay(amount);}protected void sendReceipt() {System.out.println("Receipt sent to customer.");} }// 具体的支付流程类可以根据需要进行扩展 public class OnlineStorePaymentProcess extends PaymentProcess {public OnlineStorePaymentProcess(PaymentStrategy paymentStrategy) {super(paymentStrategy);}@Overrideprotected void selectItem() {System.out.println("Item selected from online store.");}@Overrideprotected void enterShippingDetails() {System.out.println("Online store shipping details entered.");}@Overrideprotected void sendReceipt() {System.out.println("Online store receipt sent to customer.");} }