上海网站建设工资多少,网站首页效果图怎么做,优化培训课程,jsp sql 网站开发文章目录 1 基本介绍2 案例2.1 Season 接口2.2 Spring 类2.3 Summer 类2.4 Autumn 类2.5 Winter 类2.6 Person 类2.7 Client 类2.8 Client 类的运行结果2.9 总结 3 各角色之间的关系3.1 角色3.1.1 State ( 状态 )3.1.2 ConcreteState ( 具体的状态 )3.1.3 Context ( 上下文 )3.… 文章目录 1 基本介绍2 案例2.1 Season 接口2.2 Spring 类2.3 Summer 类2.4 Autumn 类2.5 Winter 类2.6 Person 类2.7 Client 类2.8 Client 类的运行结果2.9 总结 3 各角色之间的关系3.1 角色3.1.1 State ( 状态 )3.1.2 ConcreteState ( 具体的状态 )3.1.3 Context ( 上下文 )3.1.4 Client ( 客户端 ) 3.2 类图 4 注意事项5 优缺点6 适用场景7 总结 1 基本介绍
状态模式State Pattern是一种 行为型 设计模式它 允许一个对象在其内部状态改变时改变它的行为使得这个对象 看起来像是修改了它的类。
2 案例
本案例显示了 人 在 不同的季节 中 享受不同的假期 和 穿不同的上衣 的情况季节的变化通过月份的变化而实现。
2.1 Season 接口
public interface Season { // 季节String getName(); // 季节名称void festivals(); // 节日情况void dress(); // 上衣的穿着情况
}2.2 Spring 类
public class Spring implements Season { // 春季// 单例模式private static final Spring SPRING new Spring();private Spring() {}public static Spring getInstance() {return SPRING;}Overridepublic String getName() {return 春季;}Overridepublic void festivals() {System.out.println(春节、元宵节、清明节。);}Overridepublic void dress() {System.out.println(从 棉袄 向 短袖 过渡。);}
}2.3 Summer 类
public class Summer implements Season { // 夏季// 单例模式private static final Summer SUMMER new Summer();private Summer() {}public static Summer getInstance() {return SUMMER;}Overridepublic String getName() {return 夏季;}Overridepublic void festivals() {System.out.println(端午节、劳动节。);}Overridepublic void dress() {System.out.println(穿短袖。);}
}2.4 Autumn 类
public class Autumn implements Season { // 秋季// 单例模式private static final Autumn autumn new Autumn();private Autumn() {}public static Autumn getInstance() {return autumn;}Overridepublic String getName() {return 秋季;}Overridepublic void festivals() {System.out.println(中秋节、重阳节。);}Overridepublic void dress() {System.out.println(从 短袖 向 棉袄 过渡。);}
}2.5 Winter 类
public class Winter implements Season { // 冬季// 单例模式private static final Winter INSTANCE new Winter();private Winter() {}public static Winter getInstance() {return INSTANCE;}Overridepublic String getName() {return 冬季;}Overridepublic void festivals() {System.out.println(冬至、腊八节、除夕。);}Overridepublic void dress() {System.out.println(穿棉袄。);}
}2.6 Person 类
public class Person { // 人private int month; // 月份private Season season; // 月份对应的季节public void setMonth(int month) { // 设置月份和对应的季节if (month 1 || month 12) {throw new IllegalArgumentException(请输入正确的月份);}this.month month;if (month 2 month 5) {season Spring.getInstance();} else if (month 5 month 8) {season Summer.getInstance();} else if (month 8 month 11) {season Autumn.getInstance();} else {season Winter.getInstance();}}public void showMonth() { // 显示月份和季节的情况System.out.println( month 月是 season.getName() );}public void showNotAttendClass() { // 显示不上课的情况除了周末和寒暑假之外System.out.print(不上课的日子有);season.festivals();}public void showDress() { // 显示上衣的穿着情况System.out.print(上衣的穿着情况);season.dress();}
}2.7 Client 类
public class Client { // 客户端测试了 人在每个月 不上课的情况 和 上衣的穿着情况public static void main(String[] args) {Person person new Person();// 每隔 1 秒增加 1 个月for (int month 1; month 12; month) {person.setMonth(month);person.showMonth();person.showNotAttendClass();person.showDress();try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}2.8 Client 类的运行结果
1月是冬季
不上课的日子有冬至、腊八节、除夕。
上衣的穿着情况穿棉袄。
2月是春季
不上课的日子有春节、元宵节、清明节。
上衣的穿着情况从 棉袄 向 短袖 过渡。
3月是春季
不上课的日子有春节、元宵节、清明节。
上衣的穿着情况从 棉袄 向 短袖 过渡。
4月是春季
不上课的日子有春节、元宵节、清明节。
上衣的穿着情况从 棉袄 向 短袖 过渡。
5月是夏季
不上课的日子有端午节、劳动节。
上衣的穿着情况穿短袖。
6月是夏季
不上课的日子有端午节、劳动节。
上衣的穿着情况穿短袖。
7月是夏季
不上课的日子有端午节、劳动节。
上衣的穿着情况穿短袖。
8月是秋季
不上课的日子有中秋节、重阳节。
上衣的穿着情况从 短袖 向 棉袄 过渡。
9月是秋季
不上课的日子有中秋节、重阳节。
上衣的穿着情况从 短袖 向 棉袄 过渡。
10月是秋季
不上课的日子有中秋节、重阳节。
上衣的穿着情况从 短袖 向 棉袄 过渡。
11月是冬季
不上课的日子有冬至、腊八节、除夕。
上衣的穿着情况穿棉袄。
12月是冬季
不上课的日子有冬至、腊八节、除夕。
上衣的穿着情况穿棉袄。2.9 总结
本案例让四个季节对应四个类并且都实现了 Season 接口从而能够通过调用 Season 的接口来动态地调用具体季节的方法很好地利用了面向对象的 多态性避免了很多判断分支语句使得编写代码时更简单。
此外由于四个具体的季节类中没有成员字段所以使用 单例模式 来创建它们的对象实例。
3 各角色之间的关系
3.1 角色
3.1.1 State ( 状态 )
该角色负责 定义 根据不同状态进行不同处理的 接口。本案例中Season 接口扮演了该角色。
3.1.2 ConcreteState ( 具体的状态 )
该角色负责 实现 State 角色定义的 接口。本案例中Spring, Summer, Autumn, Winter 类都在扮演该角色。
3.1.3 Context ( 上下文 )
该角色负责 持有表示当前状态的 ConcreteState 角色的实例对象并 定义供外部使用的接口。本案例中Person 类扮演了该角色。
3.1.4 Client ( 客户端 )
该角色负责 使用 Context 角色完成具体的业务逻辑。本案例中Client 类扮演了该角色。
3.2 类图 说明
有时候 State 可以使用抽象类实现只需要注意 单继承 即可。Context 表面上聚合了 State实际上根据具体情况会聚合不同的 ConcreteState。Client 可能不会直接使用 State 和 ConcreteState而是给 Context 传递一个变量Context 根据这个变量修改自身的状态就像本案例一样Client 类给 Person 类的 setMonth() 方法传递 月份 这个参数从而修改 Person 类内部聚合的 season 对象。
4 注意事项
避免过多状态虽然状态模式可以处理多个状态但过多的状态会使系统变得复杂增加维护难度。因此在设计时应尽量控制状态的数量避免状态爆炸。遵守单一职责原则每个 ConcreteState 应该只负责一种状态的行为避免将多个状态的行为放在同一个类中。避免复杂逻辑ConcreteState 中的逻辑应该尽量简单避免在 ConcreteState 中实现复杂的业务逻辑。复杂的逻辑应该由 Context 或其他类来处理。性能考虑虽然状态模式可以提高代码的可读性和可维护性但在某些情况下由于 需要频繁地创建和销毁状态对象可能会降低系统的性能。因此应该避免不必要的对象创建和销毁可以考虑使用 单例模式、享元模式 来避免创建过多的对象。状态转换的管理状态转换有两种管理方式在使用本模式时需要选择具体的管理方式。 在 Context 中管理 优点提高 ConcreteState 的独立性程序的整体结构会更加清晰。缺点Context 必须了解所有 ConcreteState。 在各个 ConcreteState 中管理 优点每个 ConcreteState 都知道在什么情况下进行状态转换。缺点每个 ConcreteState 都必须了解所有 ConcreteState。
5 优缺点
优点
提高代码的可读性和可重用性状态模式通过明确的 ConcreteState 来表示不同的状态使得代码更加易于理解和重用。其他对象或系统也可以通过 State 与 ConcreteState 进行交互而不需要关心具体的状态实现从而提高了代码的 可读性 和 可重用性。增强系统的可维护性由于每个 ConcreteState 都封装了与特定状态相关的行为因此当需要修改某个状态的行为时只需要修改该 ConcreteState 的代码即可而不会影响到其他 ConcreteState 或 Context 的代码从而增强了系统的 可维护性。增强系统的扩展性当需要添加新的状态时只需要新增一个 ConcreteState并在 Context 中修改状态转换的逻辑即可而不需要修改其他 ConcreteState 的代码这符合开闭原则对扩展开放对修改关闭从而增强了系统的 扩展性。
缺点
增加类的数量状态模式会引入大量的 ConcreteState这可能会增加系统的复杂性和类的数量。当状态数量较多时系统的维护成本也会相应增加。状态转换的逻辑可能变得复杂在某些情况下状态之间的转换逻辑可能非常复杂这可能会导致 ConcreteState 的代码变得难以理解和维护。此外如果状态转换的逻辑不恰当还可能导致系统出现错误或不一致的行为。对开闭原则的支持有限虽然状态模式在一定程度上支持开闭原则但在某些情况下添加 新的状态 或 修改状态转换的逻辑 仍然需要修改 ConcreteState 的代码这可能会违反开闭原则使得系统的扩展性受到一定的限制。
6 适用场景
多状态行为当 一个对象具有多种状态并且这些状态会影响其行为 时可以使用状态模式。每个状态对应一个 ConcreteState封装了在该状态下对象的行为。状态转换复杂如果 对象的状态转换逻辑非常复杂并且这些转换逻辑分散在多个地方如多个条件语句或方法中那么使用状态模式可以将这些逻辑集中管理使代码更加清晰和易于维护。实现状态机状态模式是实现 状态机 的一种有效方式。状态机是 一种用于描述系统在不同状态下如何响应不同事件的模型。状态模式允许将状态机的各个状态作为独立的类来实现并通过状态转换来模拟状态机的行为。
7 总结
状态模式 是一种 行为型 设计模式它使用 多态性 来区分对象在不同状态下的不同行为避免了在多处书写多重分支语句的复杂性。在本模式中对象的 状态转换 是一个重点使用本模式之前需要明确对象的状态应该在合适变化。本模式在生产中比较常用因为现实生活中有很多实体需要有状态的概念例如用户的标签。