设计模式简单示例

简单总结一下大佬文章方方便记忆!
转载博客:23种设计模式学习导航(Java完整版)

1. 设计模式

2. 设计模式分类

2.1. 命令模式

命令模式(Command Pattern)是一种行为型设计模式,又叫动作模式或事务模式。它将请求(命令)封装成对象,使得可以用不同的请求对客户端进行参数化,具体的请求可以在运行时更改、排队或记录,它讲发出者和接收者解耦 (顺序:发出者–>命令–>接收者)

本质:封装请求

  1. 应用场景
    餐厅点餐:在一家餐厅中,服务员充当调用者,厨师充当接收者,菜品可以作为具体命令。当顾客想点菜时,服务员会将顾客的需求封装成一个命令对象,并传递给厨师。厨师根据命令对象中的信息来完成相应的烹饪工作。这样,顾客和厨师之间不需要直接沟通,而是通过命令对象来实现点餐和烹饪的解耦。

  2. 点餐场景实现

  • (1) 抽象命令(Command)- Command
public interface Command {
    //点菜
    void order();
    //取消点菜
    void cancelOrder();
}
  • (2) 接收者(Receiver)- Chef
public class Chef {
 
    public void cook() {
        System.out.println("厨师执行点菜命令:正在烹饪菜品...");
    }
 
    public void cancelCooking() {
        System.out.println("厨师执行取消命令:停止烹饪菜品!");
    }
}
  • (3) 具体命令(Concrete Command)- OrderCommand
public class OrderCommand implements Command{
    // 厨师
    private Chef chef;
 
    public OrderCommand(Chef chef) {
        this.chef = chef;
    }
 
    public void order() {
        //与具体的烹饪者(厨师)关联,执行点菜操作
        chef.cook();
    }
 
    public void cancelOrder() {
        //与具体的烹饪者(厨师)关联,执行取消点菜操作
        chef.cancelCooking();
    }
}
  • (4) 调用者(invoker)- Waitor

public class Waiter {
    //命令对象
    private Command command;
 
    public void setCommand(Command command) {
        this.command = command;
    }
 
    public void takeOrder() {
        // 服务员接收到顾客的点菜请求
        System.out.println("服务员接收到顾客(客户端)点菜请求!");
        // 执行点菜操作
        command.order();
    }
 
    public void cancelOrder() {
        // 服务员收到顾客的取消点菜请求
        System.out.println("服务员接收到顾客(客户端)取消点菜请求!");
        // 执行取消点菜操作
        command.cancelOrder();
    }
}

2.1. 策略模式

策略模式:策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口 和 具体行为的实现。策略模式最大的特点是行为的变化,行为之间可以相互替换。每个if判断都可以理解为就是一个策略。本模式使得算法可独立于使用它的用户而变化。

  1. 策略模式包含如下角色:
  • Strategy: 抽象策略类:策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法(如下图的algorithm())

  • Context: 环境类 /上下文类:上下文是依赖于接口的类(是面向策略设计的类,如下图Context类),即上下文包含用策略(接口)声明的变量(如下图的strategy成员变量)。上下文提供一个方法(如下图Context类中的的lookAlgorithm()方法),持有一个策略类的引用,最终给客户端调用。该方法委托策略变量调用具体策略所实现的策略接口中的方法(实现接口的类重写策略(接口)中的方法,来完成具体功能)

  • ConcreteStrategy: 具体策略类:具体策略是实现策略接口的类(如下图的ConcreteStrategyA类和ConcreteStrategyB类)。具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体方法。(说白了就是重写策略类的方法!)作。这样,顾客和厨师之间不需要直接沟通,而是通过命令对象来实现点餐和烹饪的解耦。

  1. 应用场景
    假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的高级会员提供每本20%的促销折扣:对中级会员提供每本10%的促销折扣;对初级会员没有折扣。

    • 根据描述,折扣是根据以下的几个算法中的一个进行的:
    • 算法一:对初级会员没有折扣。
    • 算法二:对中级会员提供10%的促销折扣。
    • 算法三:对高级会员提供20%的促销折扣。
      给出一本图书,如300元,若是高级会员,则输出价格为240元。
  2. 场景实现

  • (1) 抽象类策略(Strategy)
public interface MemberStrategy {
    // 一个计算价格的抽象方法
    //price商品的价格 n商品的个数
    public double calcPrice(double price, int n);
}
  • (2) 具体实现类(Concrete Strategy)
// 普通会员——不打折
public class PrimaryMemberStrategy implements MemberStrategy { // 实现策略
    //重写策略方法具体实现功能
    @Override
    public double calcPrice(double price, int n) {
        return price * n;
    }
}
// 普通会员——不打折
// 中级会员 打百分之10的折扣
public class IntermediateMemberStrategy implements MemberStrategy{
    @Override
    public double calcPrice(double price, int n) {
        double money = (price * n) - price * n * 0.1;
        return money;
    }
}
// 普通会员——不打折
// 高级会员类 20%折扣
public class AdvanceMemberStrategy implements MemberStrategy{
    @Override
    public double calcPrice(double price, int n) {
        double money = price * n - price * n * 0.2;
        return money;
    }
}
  • (3) 上下文累(Context )
/**
 * 负责和具体的策略类交互
 * 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
 */

// 上下文类/环境类
public class MemberContext {
    // 用户折扣策略接口
    private MemberStrategy memberStrategy;

    // 注入构造方法
    public MemberContext(MemberStrategy memberStrategy) {
        this.memberStrategy = memberStrategy;
    }

    // 计算价格
    public double qoutePrice(double goodsPrice, int n){
        // 通过接口变量调用对应的具体策略
        return memberStrategy.calcPrice(goodsPrice, n);
    }

}

2.3. 工厂模式 (Factory)

工厂模式:工厂模式属于创建型设计模式,它用于解耦对象的创建和使用。通常情况下,我们创建对象时需要使用new操作符,但是使用new操作符创建对象会使代码具有耦合性。工厂模式通过提供一个公共的接口,使得我们可以在不暴露对象创建逻辑的情况下创建对象。

  • 工厂模式分为三种类型:
    • 简单工厂
    • 方法工厂
    • 抽象工厂

本质: 对获取对象过程的抽象。\

  1. 工厂模式包含如下角色:
  • Factory(工厂角色)工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有实例的内部逻辑;工厂类可以直接被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法factoryMethod(),它返回一个抽象产品类Product,所有的具体产品都是抽象产品的子类。
  • Product(抽象产品角色)抽象产品角色是简单工厂模式所创建的所有对象的父类,负责描述所有实例所共有的公共接口,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个工厂方法,因为所有创建的具体产品对象都是其子类对象。
  • ConcreteProduct(具体产品类)具体产品角色是简单工厂模式的创建目标,所有创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品中的抽象方法 。
  1. 应用场景
    假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的高级会员提供每本20%的促销折扣:对中级会员提供每本10%的促销折扣;对初级会员没有折扣。

    • 根据描述,折扣是根据以下的几个算法中的一个进行的:
    • 算法一:对初级会员没有折扣。
    • 算法二:对中级会员提供10%的促销折扣。
    • 算法三:对高级会员提供20%的促销折扣。
      给出一本图书,如300元,若是高级会员,则输出价格为240元。
  2. 场景实现

  • (1) 抽象产品类(Strategy)

/**
 * @author Evan Walker
 * @version 1.0
 * @desc 昂焱数据: https://www.ayshuju.com
 * @date 2023/04/04 13:41:41
 */
public interface Fruit {
    String getColor();
}`
  • (2) 实际产品类(Concrete Strategy)
/**
 * @author Evan Walker
 * @version 1.0
 * @desc 昂焱数据: https://www.ayshuju.com
 * @date 2023/04/04 13:41:41
 */
public class Apple implements Fruit{
    @Override
    public String getColor() {
        return "红色";
    }
}
public class Orange implements Fruit{
    @Override
    public String getColor() {
        return "橙色";
    }
}
public class Pear implements Fruit{
    @Override
    public String getColor() {
        return "黄色";
    }
}
  • (3) 工厂角色( Factory )
/**
 * @author Evan Walker
 * @version 1.0
 * @desc 昂焱数据: https://www.ayshuju.com
 * @date 2023/04/04 13:44:44
 */
public class FruitFactory {
    public Fruit createFruit(String fruitType) {
        if(fruitType.equalsIgnoreCase("Apple")){
            return new Apple();
        } else if(fruitType.equalsIgnoreCase("Orange")) {
            return new Orange();
        }else if(fruitType.equalsIgnoreCase("Pear")){
            return new Pear();
        }
        return null;
    }
}

2.4. 建造者模式

建造者模式:封装一个复杂对象的构建过程,并允许按步骤构建。

  1. 建造着模式包含如下角色:
  • 产品类(Productiom):表示被构建的复杂对象,通常包含多个组成部分,由建造者逐步构建完成。
  • 抽象构建者(Builder):定义了构建复杂对象所需要的各个部分的构建方法。
  • 具体构建者(ConcreteBuilder):实现各个接口,并提供各个产品类各个部分的构建方法。
  • 指挥者类(Director):读者构建者的构建顺序,指挥构建者如何构建复杂对象。
  1. 应用场景
    肯德基套餐的实现:假设套餐主要由汉堡、薯条和饮料三种组成,每个组件都有不同种类和大小,并且每个套餐的组合方式也不同。下面以肯德徳套餐为例,解释建造者模式。

    • 产品类:Meal
    • 抽象构建者:MealBuilder
    • 具体构建者:BeefBurgerMealBuilder, ChickenMealBuilder、ShrimpMealBuilder
    • 指挥者类:MealDirector
    1. 场景实现
  • (1)象产品类: Meal
public class Meal {
 
    //汉堡包
    private String burger;
 
    //薯条
    private String fries;
 
    //饮料
    private String drink;
}
  • (2) 抽象构建者(MealBuilder)

public abstract class MealBuilder {
 
    protected Meal meal=new Meal();
 
    //构建汉堡
    public abstract void buildBurger();
 
    //构建薯条
    public abstract void buildFries();
 
    //构建饮料
    public abstract void buildDrink();
 
    public Meal getMeal(){
        return meal;
    }
}
  • (3) 具体构建者( BeefBurgerMealBuilder, ChickenMealBuilder、ShrimpMealBuilder)

public class ChickenMealBuilder extends MealBuilder{
    @Override
    public void buildBurger() {
        meal.setBurger("鸡肉汉堡");
    }
 
    @Override
    public void buildFries() {
        meal.setFries("中份薯条");
    }
 
    @Override
    public void buildDrink() {
        meal.setDrink("大杯果汁");
    }
}

public class BeefBurgerMealBuilder extends MealBuilder {
 
    @Override
    public void buildBurger() {
        meal.setBurger("牛肉汉堡");
    }
 
    @Override
    public void buildFries() {
        meal.setFries("大份薯条");
    }
 
    @Override
    public void buildDrink() {
        meal.setDrink("中杯可乐");
    }
}

public class ShrimpMealBuilder extends MealBuilder {
    @Override
    public void buildBurger() {
        meal.setBurger("虾肉汉堡");
    }
 
    @Override
    public void buildFries() {
        meal.setFries("小份薯条");
    }
 
    @Override
    public void buildDrink() {
        meal.setDrink("大杯芬达");
    }

}
  • (4) 指导者(Director)
public class MealDirector {
    private MealBuilder mealBuilder;
 
    public void setMealBuilder(MealBuilder mealBuilder){
        this.mealBuilder=mealBuilder;
    }
 
    public Meal getMeal(){
        return mealBuilder.getMeal();
    }
 
    //制作套餐
    public void constructMeal(){
        mealBuilder.buildBurger();
        mealBuilder.buildFries();
        mealBuilder.buildDrink();
    }
}
`
 (5)  测试类


```java
public class TestBuilder {
 
    @Test
    void testBuilder(){
        //创建指导者
        MealDirector director=new MealDirector();
 
        //执导建造牛肉套餐
        director.setMealBuilder(new BeefBurgerMealBuilder());
        director.constructMeal();
        Meal meal = director.getMeal();
        System.out.println("牛肉套餐:"+meal.toString());
 
        //鸡肉套餐
        director.setMealBuilder(new ChickenMealBuilder());
        director.constructMeal();
        Meal meal2 = director.getMeal();
        System.out.println("鸡肉套餐:"+meal2.toString());
 
        //虾肉套餐
        director.setMealBuilder(new ShrimpMealBuilder());
        director.constructMeal();
        Meal meal3 = director.getMeal();
        System.out.println("虾肉套餐:"+meal3.toString());
    }
}

相关推荐

  1. 设计模式简单示例

    2024-07-09 16:50:08       24 阅读
  2. 设计模式示例

    2024-07-09 16:50:08       35 阅读
  3. 设计模式:策略模式示例

    2024-07-09 16:50:08       26 阅读
  4. 设计模式:组合模式示例

    2024-07-09 16:50:08       31 阅读
  5. 设计模式:命令模式示例

    2024-07-09 16:50:08       32 阅读
  6. 设计模式:状态模式示例

    2024-07-09 16:50:08       30 阅读
  7. 简单设计模式讲解

    2024-07-09 16:50:08       34 阅读
  8. 设计模式-简单工厂

    2024-07-09 16:50:08       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 16:50:08       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 16:50:08       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 16:50:08       45 阅读
  4. Python语言-面向对象

    2024-07-09 16:50:08       55 阅读

热门阅读

  1. CSS里的几个小知识

    2024-07-09 16:50:08       32 阅读
  2. 社交媒体原生应用开发:Facebook的创新之路

    2024-07-09 16:50:08       33 阅读
  3. Gunicorn+Flask+Docker初体验

    2024-07-09 16:50:08       26 阅读
  4. 常用目标检测的格式转换脚本文件txt,json等

    2024-07-09 16:50:08       26 阅读
  5. 信息收集-arping

    2024-07-09 16:50:08       23 阅读
  6. flutter如何实现点击一文字后 打开对应的超链接

    2024-07-09 16:50:08       23 阅读
  7. TCP协议是安全的吗?

    2024-07-09 16:50:08       47 阅读