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

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

〇、小故事

小王开了一个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

public interface ComputerComponent {
    int price(); // 售价
    String version(); // 硬件版本
    String desc(); // 描述
    void accept(Visitor visitor);
}

创建CPU类Cpu.java

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

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

public interface Visitor {
    void visitorCpu(Cpu cpu);
    void visitorMemory(Memory memory);
    int price();
    String visiterName();
}

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

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

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

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

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

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()));
    }
}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

相关文章
|
设计模式
趣解设计模式之《小王的披萨店续集》
趣解设计模式之《小王的披萨店续集》
75 0
|
设计模式
趣解设计模式之《当代毕加索小王》
趣解设计模式之《当代毕加索小王》
53 0
|
设计模式
趣解设计模式之《小王的糖果售卖机》
趣解设计模式之《小王的糖果售卖机》
74 0
|
设计模式
趣解设计模式之《小王的披萨店》
趣解设计模式之《小王的披萨店》
50 1
|
设计模式 数据采集 搜索推荐
趣解设计模式之《小王设计的疫苗管理平台系统》
趣解设计模式之《小王设计的疫苗管理平台系统》
58 0
|
设计模式
趣解设计模式之《珍爱生命,远离只狼》
趣解设计模式之《珍爱生命,远离只狼》
97 0
|
设计模式 存储 运维
趣解设计模式之《庞大的组织架构带来的烦恼》
趣解设计模式之《庞大的组织架构带来的烦恼》
49 0
|
设计模式 算法
趣解设计模式之《会飞的橡皮鸭》
趣解设计模式之《会飞的橡皮鸭》
101 0
|
16天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。