设计模式八股文

什么是设计模式?

设计模式是软件开发过程中经常遇到的问题的通用解决方案。类似于前人总结的经验,遇到相似问题的时候有个参考。

设计模式七大基本原则?

  • 单一职责:一个类应该只作一件事情。将功能分为小的独立的单元。
  • 开放封闭原则:对扩展开放,对修改关闭。
  • 里氏替换原则:任何一个父类出现的地方,都可以用子类替换,而不会导致错误或者异常。
  • 依赖倒置:高层模块不应该依赖于底层,应该依赖于抽象,实现解耦。
  • 接口隔离:一个类不应该强迫它的客户端依赖于它们不需要的方法,接口应该小而专注,不应该包含多余的方法。

责任链模式?

  • 一种行为型设计模式,使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合。
  • 请求沿着链传递,直到有对象处理为止。
  • 分为三个角色:
    • Handler:抽象处理者,定义了一个处理请求的接口或者抽象类,通常会包含一个指向链中下一个处理者的引用。
    • ConcreteHandler:具体处理者,实现抽象处理者的处理方法,如果能处理就处理,不能就转发给下一个。
    • client:客户端,创建处理链,并向链的第一个处理者对象提交请求。
  • 工作流程:
    • 客户端将请求发送给链上的第一个处理者对象
    • 接收到请求后是否能处理
      • 可以就处理
      • 不可以就转发给链上的下一个处理者
    • 过程重复
  • 场景:
    • 过滤器链
    • 日志记录
    • 异常处理
    • 认证授权
  • 优缺点:
    • 降低耦合度
  • 实际举例:
    • 比如在线商店,用户下单的时候需要
      • 检查订单信息是否完整
      • 检查商品库存是否充足
      • 检查用户余额是否充足
      • 确认订单,更新商品库存和用户余额
java 复制代码
public interface OrderHandler{
    void handler(Order order);
}
java 复制代码
public class CheckOrderHandler implements OrderHandler {
    private OrderHandler next;

    public CheckOrderHandler(OrderHandler next) {
        this.next = next;
    }

    @Override
    public 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;
        }

        @Override
        public 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;
        }

        @Override
        public void hand1e(Order order) {
//检查用户余额是否充足.
            if (order.getBalance() >= order.getAmount()) {
//如果余额充足,则将请求传递给下一个处理者.
                next.handle(order); 
            } else {
//如果余额不足,则直接返回错误信息
                throw new RuntimeException("用户 余额不足");
            }
        }
    }

    public class ConfirmOrderHandler implements OrderHandler {
        @Override
        public void handle(Order order) {
//确认订单,更新商品库存和用户余额
            order.confirm();
        }
    }
java 复制代码
//客户端代码示例
        CheckOrderHandler checkOrderHandler = new
                CheckOrderHandler();
        CheckStockHandler checkStockHandler = new CheckStockHand1er();
        CheckBalanceHandler checkBalanceHandler = new CheckBalanceHandler();
        ConfirmOrderHandler conf
        irmOrderHandler =new

                ConfirmOrderHand1er();
//将处理器按照一定顺序组成责任链
        checkOrderHand1er.setNext(checkStockHandler);
        checkStockHand1er.setNext(checkBalanceHandler);
        checkBalanceHand1er.setNext(confirmOrderHandler);
        // 处理订单
        Order order = new Order();
        checkOrderHandler.handle(order);

工厂模式?

  • 创建型设计模式主要创建对现象,而不暴露对象的逻辑给客户端。

  • 简单工厂

    • 简单工厂模式的角色包括三个:

      • 抽象产品 角色

      java 复制代码
      public abstract class Weapon {
          /**
           * 所有的武器都有攻击行为
           */
          public abstract void attack();
      }
      • 具体产品角色

      java 复制代码
      public class Tank extends Weapon{
          @Override
          public void attack() {
              System.out.println("坦克开炮!");
          }
      }
      
      
      /**
       * 战斗机(具体产品角色)
       * @version 1.0
       * @className Fighter
       * @since 1.0
       **/
      public class Fighter extends Weapon{
          @Override
          public void attack() {
              System.out.println("战斗机投下原子弹!");
          }
      }
      
      
      /**
       * 匕首(具体产品角色)
       * @version 1.0
       * @className Dagger
       * @since 1.0
       **/
      public class Dagger extends Weapon{
          @Override
          public void attack() {
              System.out.println("砍他丫的!");
          }
      }
      • 工厂类 角色

      java 复制代码
      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通过依赖注入和面向接口编程解决
  • 工厂方法

    • 工厂方法模式既保留了简单工厂模式的优点,同时又解决了简单工厂模式的缺点。

      工厂方法模式的角色包括:

      • 抽象工厂角色

      java 复制代码
      /**
       * 武器工厂接口(抽象工厂角色)
       * @author 动力节点
       * @version 1.0
       * @className WeaponFactory
       * @since 1.0
       **/
      public interface WeaponFactory {
          Weapon get();
      }
      • 具体工厂角色

      java 复制代码
      /**
       * 具体工厂角色
       * @author 动力节点
       * @version 1.0
       * @className GunFactory
       * @since 1.0
       **/
      public class GunFactory implements WeaponFactory{
          @Override
          public Weapon get() {
              return new Gun();
          }
      }
      package com.powernode.factory;
      
      /**
       * 具体工厂角色
       * @author 动力节点
       * @version 1.0
       * @className FighterFactory
       * @since 1.0
       **/
      public class FighterFactory implements WeaponFactory{
          @Override
          public Weapon get() {
              return new Fighter();
          }
      }
      • 抽象产品角色

      java 复制代码
      /**
       * 武器类(抽象产品角色)
       * @author 动力节点
       * @version 1.0
       * @className Weapon
       * @since 1.0
       **/
      public abstract class Weapon {
          /**
           * 所有武器都有攻击行为
           */
          public abstract void attack();
      }
      • 具体产品角色

      java 复制代码
      /**
       * 具体产品角色
       * @author 动力节点
       * @version 1.0
       * @className Gun
       * @since 1.0
       **/
      public class Gun extends Weapon{
          @Override
          public void attack() {
              System.out.println("开枪射击!");
          }
      }
      package com.powernode.factory;
      
      /**
       * 具体产品角色
       * @author 动力节点
       * @version 1.0
       * @className Fighter
       * @since 1.0
       **/
      public class Fighter extends Weapon{
          @Override
          public void attack() {
              System.out.println("战斗机发射核弹!");
          }
      }

      扩展时增加一个产品+工厂,缺点:类爆炸

  • 抽象工厂模式:


    抽象工厂中包含4个角色:

    • 抽象工厂角色

    ```java
    public abstract class AbstractFactory {
        public abstract Weapon getWeapon(String type);
        public abstract Fruit getFruit(String type);
    }
    ```
    
    • 具体工厂角色

    ```java
    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("无法生产该武器");
            }
        }
    
        @Override
        public Fruit getFruit(String type) {
            return null;
        }
    }
    
    
    
    public class FruitFactory extends AbstractFactory{
        @Override
        public 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("我家果园不产这种水果");
            }
        }
    }
    ```
    
    • 抽象产品角色

    • 具体产品角色

    ```java
    public abstract class Weapon {
        public abstract void attack();
    }
    package com.powernode.product;
    
    
    public class Gun extends Weapon{
        @Override
        public void attack() {
            System.out.println("开枪射击!");
        }
    }
    
    public class Dagger extends Weapon{
        @Override
        public void attack() {
            System.out.println("砍丫的!");
        }
    }
    ```
    
    优点:能保证一个工厂只使用一个类型的
    * 缺点:不符合OCP、
    

单例模式?

见另一篇

策略模式和模板设计模式?

  • 策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法独立于使用它的客户而变化。
java 复制代码
// 定义策略接口
public interface PaymentStrategy {
    void pay(int amount);
}

// 具体策略类:信用卡支付
public class CreditCardPaymentStrategy implements PaymentStrategy {
    private String cardNumber;

    public CreditCardPaymentStrategy(String cardNumber) {
        this.cardNumber = cardNumber;
    }

    @Override
    public 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;
    }

    @Override
    public 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);
    }
}
  • 模板方法模式:

    • 模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
    java 复制代码
    // 抽象类,定义模板方法和抽象方法
    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 {
        @Override
        protected void initialize() {
            System.out.println("Football Game Initialized! Start playing.");
        }
    
        @Override
        protected void startPlay() {
            System.out.println("Football Game Started. Enjoy the game!");
        }
    
        @Override
        protected void endPlay() {
            System.out.println("Football Game Finished!");
        }
    }
    
    // 具体类:篮球游戏
    public class Basketball extends Game {
        @Override
        protected void initialize() {
            System.out.println("Basketball Game Initialized! Start playing.");
        }
    
        @Override
        protected void startPlay() {
            System.out.println("Basketball Game Started. Enjoy the game!");
        }
    
        @Override
        protected 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();
        }
    }

    结合:
    *

    java 复制代码
    // 定义支付策略接口
    public interface PaymentStrategy {
        void pay(int amount);
    }
    
    // 具体支付策略类:信用卡支付
    public class CreditCardPaymentStrategy implements PaymentStrategy {
        private String cardNumber;
    
        public CreditCardPaymentStrategy(String cardNumber) {
            this.cardNumber = cardNumber;
        }
    
        @Override
        public 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;
        }
    
        @Override
        public void pay(int amount) {
            System.out.println("Paid " + amount + " using PayPal: " + email);
        }
    }
    java 复制代码
    // 抽象类,定义支付流程的模板方法
    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);
        }
    
        @Override
        protected void selectItem() {
            System.out.println("Item selected from online store.");
        }
    
        @Override
        protected void enterShippingDetails() {
            System.out.println("Online store shipping details entered.");
        }
    
        @Override
        protected void sendReceipt() {
            System.out.println("Online store receipt sent to customer.");
        }
    }
相关推荐
数据小爬虫@11 分钟前
如何高效利用Python爬虫按关键字搜索苏宁商品
开发语言·爬虫·python
ZJ_.13 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
Narutolxy18 分钟前
深入探讨 Go 中的高级表单验证与翻译:Gin 与 Validator 的实践之道20241223
开发语言·golang·gin
Hello.Reader25 分钟前
全面解析 Golang Gin 框架
开发语言·golang·gin
禁默36 分钟前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood43 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑1 小时前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
gb42152871 小时前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
程序猿进阶1 小时前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
qq_433618441 小时前
shell 编程(二)
开发语言·bash·shell