设计模式之状态模式

简介: 在网上买东西都见过一件9折,两件5折,限购两件等等这样的宣传语,我们买不同数量的衣服,就会有不同的折扣,这就是今天所讲的状态模式。

一、认识状态模式


1、概念


状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。


也就是说,我们把不同的状态包装成一个抽象类,每一个状态都成为一个独立的类。当状态不同时,处理的状态类也就不同了。如果难以理解我们拿上面商场打折扣的那个例子来说明。我们买衣服的时候,商家会把客户买多少衣服封装成一个抽象类,客户买一件衣服,那就使用买一件打九折的机制去处理,客户买两件,那就使用买两件打5折的机制去处理。但是限购两件,当用户买三件的话直接拉入黑名单。

还不理解的话,再来个类图看看。


2、类图

v2-6d44589689e84c22d1c5200def7267d5_1440w.jpg

从上图可以看出,状态模式所涉及到的角色有3个:


(1)环境(Context)角色,也成上下文:定义操作的方法。

(2)抽象状态(State)角色:这里表示折扣接口,用户封装行为。

(3)具体状态(ConcreteState)角色:这里指具体的折扣类。


看起来和策略模式一样,但是最后分析一下就清楚了。下面我们使用代码来演示一下状态模式到底是什么样的。


二、代码实现


第一步:定义抽象状态类

public interface Discount {
    public void discount(String user,String clothName,Context context);
}

第二步:定义具体折扣类

首先是买一件打九折:

public class Discount9 implements Discount {
    @Override
    public void discount(String user,String clothName,Context context) {
        //某用户打九折
        context.getCloth().put(user, discountType);
        System.out.println("打九折");
    }
}

然后是买两件打5折

public class Discount5 implements Discount {
    @Override
    public void discount(String user,String clothName,Context context) {
        //某用户打五折
        context.getCloth().put(user, discountType);
        System.out.println("打五折");
    }
}

最后是买三件被拉入黑名单了

public class DiscountOff implements Discount {
    @Override
    public void discount(String user,String clothName,Context context) {
        // 恶意投票,取消用户的投票资格,并取消投票记录
        String str = context.getCloth.get(user);
        if(str != null){
            context.getCloth.remove(user);
        }
        System.out.println("被拉入黑名单");
    }
}

第三部:具体环境类

public class Context {
    private Discount discount = null;
    //把每一个客户买了什么衣服记录下来
    private Map<String,String> clothMap = new HashMap<String,String>();
    //把每一个用户买了多少件衣服记录下来
    private Map<String,Integer> clothCountMap = new HashMap<String,Integer>();
    public Map<String, String> getCloth() {
        return cloth;
    }
    public void dicount(String user,String clothName){
        //1.取得客户买了多少件了:然后为其增加一件
        Integer oldClothCount = clothCountMap.get(user);
        oldClothCount += 1;
        mapVoteCount.put(user, oldClothCount);
        //2.根据客户购买的数量进行打折等处理
        if(oldClothCount == 1){
            discount = new Discount9();
        }
        else if(oldClothCount == 2){
            discount = new Discount5();
        }
        else if(oldClothCount >= 3){
            discount = new DiscountOff();
        }
        //然后转调状态对象来进行相应的操作
        discount.discount(user, clothName, this);
    }
}

第四步:我们就演示一下整个状态模式

public class Client {
    public static void main(String[] args) { 
        Context context = new Context();
        //张三买了裤子A:第一件
        context.discount("张三","裤子A");
        //张三又买了裤子A:第二件
        context.discount("张三","裤子A");
        //张三再次买了裤子A:第三件
        context.discount("张三","裤子A");
    }
}
//输出
//打九折
//打五折
//被拉入黑名单

从上面的输出结果可以看到,我们执行不同的命令,会有不同的状态。上面的衣服买一件打九折,买两件打五折,因为限购两件,所以再买一件的时候就直接被拉入黑名单了。


下面我们来分析一下这个状态模式


三、分析状态模式


状态模式的优点相信你也体会到了,可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。


但是缺点也很明显,那就是当我们的状态比较多的时候,类也比较多,会使得代码显得非常的臃肿。而且context内部实现也比较复杂,没有完全的遵循设计原则。

这里主要看一下和状态模式的区别,这个状态模式乍一看还真的跟策略模式长得差不多,为了使得理解起来方便,举个例子吧。


策略模式就好比你单身的时候,女朋友随时换。你要在这些女朋友之间处理好关系,游刃有余。但是状态模式就不一样了,这就好比你结了婚,娶了老婆。每天就只在自己老婆身边转,去处理即可。再通俗一点,就是策略模式服务的对象是不固定的,但是状态模式服务的对象是固定的,每次都是那一个。

相关文章
|
7月前
|
设计模式
设计模式之 State(状态模式)
设计模式之 State(状态模式)
43 0
|
3月前
|
设计模式 Java 测试技术
Java设计模式-状态模式(18)
Java设计模式-状态模式(18)
|
4月前
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)
|
5月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
83 7
|
6月前
|
设计模式
状态模式-大话设计模式
状态模式-大话设计模式
|
6月前
|
设计模式 存储
行为设计模式之状态模式
行为设计模式之状态模式
|
7月前
|
设计模式 Go
[设计模式 Go实现] 行为型~状态模式
[设计模式 Go实现] 行为型~状态模式
|
7月前
|
设计模式 Java
23种设计模式,状态模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】状态模式是一种行为设计模式,允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
60 4
|
7月前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
|
7月前
|
设计模式 Java
【设计模式系列笔记】状态模式
在Java中,状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为。状态模式的关键思想是将对象的状态封装成独立的类,并将对象的行为委托给当前状态的对象。这样,当对象的状态发生变化时,其行为也会相应地发生变化。
79 0