前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >趣解设计模式之《小王与他的Apple商店》

趣解设计模式之《小王与他的Apple商店》

作者头像
爪哇缪斯
发布2023-09-23 15:33:48
1230
发布2023-09-23 15:33:48
举报
文章被收录于专栏:爪哇缪斯爪哇缪斯

〇、小故事

小王开了一个Apple商店,每天销售量都很不错,但是,近期却有一件事让他很苦恼,那就是针对不同的角色用户,商品的售价是各不同的

比如说,对于普通消费者来说,对于最新的Apple产品,都是原价销售的;

那么,对于学生消费群体来说,由于每年开学都会有高校折扣的政策,为了减少学生客户群体的购买压力,是在原价的基础上打8折销售的;

那么,对于企业大客户来说,很多互联网公司都会采购Apple电脑作为办公电脑,往往这种企业采购的方式购买电脑的数量会非常的大。所以,为了促进与企业的合作,是在原价的基础上打5折销售的;

随着后续购买用户角色类型的增多,就会造成一大堆的if-else判断逻辑,来返回不同角色对应的不同价格,这样无疑会使得代码维护性越来越差,那有什么更好的办法解决这个问题吗?当然有了,解决办法就是我们今天要介绍的设计模式——访问者模式

一、模式定义

访问者模式Visitor Pattern

表示一个作用于某个对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作

根据上面的小故事,我们可以看到小王的主要困扰就是针对不同的用户类型要有不同的折扣,这样随着用户类型的增多或者减少,我们都要频繁的修改电脑组件类(CPUMemory)里的if-else价格判断逻辑。那我们来思考一下,哪些是变化的?哪些是不变的呢?

变化】用户类型,如:普通用户学生用户企业采购用户…… 【不变】计算机组件类标准价格(此处我们不考虑促销活动的折扣或免减),如:CPUMemory……

既然变化的是用户类型,那么我们何不把计算机组件中判断金额的逻辑部分转移到用户类型中呢?这样计算机组件就永久稳定了。

有了这样的想法之后,计算机组件每个类都只需要包含标价就可以了。然后,针对不同的用户类型打不同的折扣,这部分逻辑,就可以抽离到计算机组件类中

二、模式类图

根据上面的描述,我们首先来创建计算机组件接口ComputerComponent.java,以及两个计算机组件的实现类CPU.javaMemory.java。然后再创建计算机类Computer.java,用于将计算机的各个组件类组合起来。那么针对不同的用户类型,我们首先创建访问者接口Visitor.java,然后创建3个实现类,分别是普通用户访问者PersonVisitor.java学生用户访问者StudentVisitor.java企业采购访问者CompanyVisitor.java。具体类图请见如下所示:

三、代码实现

创建计算机组件类ComputerComponent.java

代码语言:javascript
复制
public interface ComputerComponent {
    int price(); // 售价
    String version(); // 硬件版本
    String desc(); // 描述
    void accept(Visitor visitor);
}

创建CPU类Cpu.java

代码语言:javascript
复制
public class Cpu implements ComputerComponent {
    public int price = 100; // 全国标准售价
    @Override
    public int price() {
        return 100;
    }
    @Override
    public String version() {
        return "v1";
    }
    @Override
    public String desc() {
        return "英特尔CPU";
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visitorCpu(this);
    }
}

创建内存类Memory.java

代码语言:javascript
复制
public class Memory implements ComputerComponent {
    public int price = 400; // 全国标准售价
    @Override
    public int price() {
        return price;
    }
    @Override
    public String version() {
        return "v4";
    }
    @Override
    public String desc() {
        return "金士顿内存";
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visitorMemory(this);
    }
}

创建访问者类Visitor.java

代码语言:javascript
复制
public interface Visitor {
    void visitorCpu(Cpu cpu);
    void visitorMemory(Memory memory);
    int price();
    String visiterName();
}

创建个人用户类(不打折)PersonVisitor.java

代码语言:javascript
复制
public class PersonVisitor implements Visitor {
    public int totalPrice; // 总售价
    @Override
    public void visitorCpu(Cpu cpu) {
        totalPrice += cpu.price();
    }
    @Override
    public void visitorMemory(Memory memory) {
        totalPrice += memory.price();
    }
    @Override
    public int price() {
        return totalPrice;
    }
    @Override
    public String visiterName() {
        return "个人用户";
    }
}

创建学生用户(校园计划,打8折)StudentVisitor.java

代码语言:javascript
复制
public class StudentVisitor implements Visitor {
    public int totalPrice; // 总售价
    @Override
    public void visitorCpu(Cpu cpu) {
        totalPrice += cpu.price() * 0.8;
    }
    @Override
    public void visitorMemory(Memory memory) {
        totalPrice += memory.price() * 0.9;
    }
    @Override
    public int price() {
        return totalPrice;
    }
    @Override
    public String visiterName() {
        return "学生用户";
    }
}

创建公司大客户(打5折)CompanyVisitor.java

代码语言:javascript
复制
public class CompanyVisitor implements Visitor {
    public int totalPrice; // 总售价
    @Override
    public void visitorCpu(Cpu cpu) {
        totalPrice += cpu.price() * 0.5;
    }
    @Override
    public void visitorMemory(Memory memory) {
        totalPrice += memory.price() * 0.4;
    }
    @Override
    public int price() {
        return totalPrice;
    }
    @Override
    public String visiterName() {
        return "公司大客户";
    }
}

创建计算机类,组合上面的组件Computer.java

代码语言:javascript
复制
public class Computer {
    private ComputerComponent memory;
    private ComputerComponent cpu;
    public Computer() {
        memory = new Memory();
        cpu = new Cpu();
    }
    
    /**
     * 攒机方法
     * @Visitor 买电脑的客户角色
     */
    public void buildComputer(Visitor visitor) {
        // 买cpu
        cpu.accept(visitor);
        // 买内存
        memory.accept(visitor);
    }
}

创建测试类VisitorTest.java

代码语言:javascript
复制
public class VisitorTest {
    public static void main(String[] args) {
        Computer computer = new Computer();
        Visitor personVisitor = new PersonVisitor();
        Visitor studentVisitor = new StudentVisitor();
        Visitor companyVisitor = new CompanyVisitor();
        
        computer.buildComputer(personVisitor);
        System.out.println(String.format("针对%s,每台电脑售价为:%s元", personVisitor.visiterName(), personVisitor.price()));
        
        computer.buildComputer(studentVisitor);
        System.out.println(String.format("针对%s,每台电脑售价为:%s元", studentVisitor.visiterName(), studentVisitor.price()));
        
        computer.buildComputer(companyVisitor);
        System.out.println(String.format("针对%s,每台电脑售价为:%s元", companyVisitor.visiterName(), companyVisitor.price()));
    }
}

往期推荐

趣解设计模式之《珍爱生命,远离只狼》

趣解设计模式之《庞大的组织架构带来的烦恼》

趣解设计模式之《会飞的橡皮鸭》

趣解设计模式之《小王的学习秘籍》

趣解设计模式之《我买了宝马,为啥不让我停这?》

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-09-23 09:30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爪哇缪斯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 〇、小故事
  • 一、模式定义
  • 二、模式类图
  • 三、代码实现
  • 往期推荐
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档