美文网首页
设计模式 - 17.状态模式 [行为型模式]

设计模式 - 17.状态模式 [行为型模式]

作者: Zszen | 来源:发表于2020-03-27 01:30 被阅读0次
大纲 小结
基础准则 基础准则
创建型模式 单例模式
- 原型模式
- 简单工厂模式
- 抽象工厂模式
- 建造者模式
结构型模式 代理模式
- 适配器模式
- 桥接模式
- 装饰器模式
- 门面/外观模式
- 享元模式
- 组合模式
行为型模式 模板方法模式
- 策略模式
- 命令模式
- 职责链模式
- 状态模式
- 观察者模式
- 中介者模式
- 迭代器模式
- 访问者模式
- 备忘录模式
- 解释器模式

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

这次做的复杂了一点点, 结合了责任链模式和状态模式共同完成了特殊日期展示
通过责任链, 查找复杂条件下对应日期的描述, 也通过它可以反复使用和切换状态, 避免了反复创建的问题
通过状态机得到当前日期对应的日期描述
( 状态模式通过状态来改变依赖关系, 有点违背了依赖倒置原则, 所以这里我改成了责任链, 所以这里不是完整的状态模式)

import abc
import datetime

class DateMean:
    def __init__(self):
        d1 = DateDes_f_11()
        self._datedesc_def = d1
        self._datedesc_cur = d1
        d2 = DateDes_f_38()
        d1.next = d2
        d1 = d2
        d2 = DateDes_f_51()
        d1.next = d2
        d1 = d2
        d2 = DateDes_f_61()
        d1.next = d2
        d1 = d2
        d2 = DateDes_f_101()
        d1.next = d2
        d1 = d2
        d2 = DateDes_f_1111()
        d1.next = d2
        d1 = d2
        d2 = DateDes_each1wes()
        d1.next = d2
        d1 = d2
        d2 = DateDes_weekend()
        d1.next = d2
        d1 = d2
        d2 = DateDes_Normal()
        d1.next = d2
        d1 = d2

    def setDate(self, year, month, day):
        self._datedesc_cur = self._datedesc_def.find(year,month,day)

    def descript(self):
        return self._datedesc_cur.name


class IDateDes(metaclass=abc.ABCMeta):
    def __init__(self):
        self._next:IDateDes = None
        self.year = 0
        self.month = 0
        self.day = 0
        self.name = None
        pass

    @property
    def next(self):
        return self._next

    @next.setter
    def next(self,nexter):
        self._next = nexter
    
    @abc.abstractmethod
    def find(self, year,month,day):
        pass

class DateDes_Normal(IDateDes):
    def __init__(self):
        super().__init__()
        self.name = '普通的一天'

    def find(self, year, month, day):
        return self

class DateDes_festival(IDateDes):
    def __init__(self):
        super().__init__()
        self.name = '节日'

    def find(self, year, month, day):
        if month==self.month and day==self.day:
            return self
        else:
            return self.next.find(year, month, day)


class DateDes_f_11(DateDes_festival):
    def __init__(self):
        super().__init__()
        self.name = '元旦'
        self.month = 1
        self.day = 1

class DateDes_f_38(DateDes_festival):
    def __init__(self):
        super().__init__()
        self.name = '三八妇女节'
        self.month = 3
        self.day = 8

class DateDes_f_51(DateDes_festival):
    def __init__(self):
        super().__init__()
        self.name = '五一劳动节'
        self.month = 5
        self.day = 1

class DateDes_f_61(DateDes_festival):
    def __init__(self):
        super().__init__()
        self.name = '儿童节'
        self.month = 6
        self.day = 1

class DateDes_f_101(DateDes_festival):
    def __init__(self):
        super().__init__()
        self.name = '十一劳动节'
        self.month = 10
        self.day = 1

class DateDes_f_1111(DateDes_festival):
    def __init__(self):
        super().__init__()
        self.name = '双十一'
        self.month = 11
        self.day = 11

class DateDes_f_1225(DateDes_festival):
    def __init__(self):
        super().__init__()
        self.name = '圣诞节'
        self.month = 12
        self.day = 25

class DateDes_weekend(IDateDes):
    def __init__(self):
        super().__init__()
        self.name = '周末'

    def find(self, year, month, day):
        if year == None:
            year = datetime.datetime.now().year
        d = datetime.datetime.strptime('%d-%d-%d'%(year,month,day),'%Y-%m-%d')
        if d.weekday() >= 5 :
            return self
        else:
            return self.next.find(year, month, day)

class DateDes_each1wes(IDateDes):
    def __init__(self):
        super().__init__()
        self.name = '每月第一个周三'

    def find(self, year, month, day):
        if day<7 :
            if year == None:
                year = datetime.datetime.now().year
            d = datetime.datetime.strptime('%d-%d-%d'%(year,month,day),'%Y-%m-%d')
            if d.weekday()==2:
                return self
            else:
                return self.next.find(year, month, day)
        else:
            return self.next.find(year, month, day)




if __name__ == '__main__':
    # dt = datetime.datetime(year=2020,month=1,day=1)
    dt = datetime.datetime.now()
    for k in range(20):
        dt_cur = dt+datetime.timedelta(k)
        d = DateMean()
        d.setDate(dt_cur.year,dt_cur.month,dt_cur.day)
        print(dt_cur.strftime('%Y-%m-%d'), d.descript())

输出

2020-03-27 普通的一天
2020-03-28 周末
2020-03-29 周末
2020-03-30 普通的一天
2020-03-31 普通的一天
2020-04-01 每月第一个周三
2020-04-02 普通的一天
2020-04-03 普通的一天
2020-04-04 周末
2020-04-05 周末
2020-04-06 普通的一天
2020-04-07 普通的一天
2020-04-08 普通的一天
2020-04-09 普通的一天
2020-04-10 普通的一天
2020-04-11 周末
2020-04-12 周末
2020-04-13 普通的一天
2020-04-14 普通的一天
2020-04-15 普通的一天

再进一步扩在, 你会发现, 要添加特殊日期, 也要在责任链中去添加, 修改的地方过多
使用抽象工厂+枚举的方案来解决这个问题

相关文章

网友评论

      本文标题:设计模式 - 17.状态模式 [行为型模式]

      本文链接:https://www.haomeiwen.com/subject/yhgxuhtx.html