状态模式的具体实现 情景三
2015-10-17 20:32
246 查看
这篇中,我们将看到一种不同于前两篇的状态模式设计方法。
状态切换器中自己维护了一张状态切换列表,而且不同的状态所执行的操作是一样的。
我们假设商品有多种不同的分类,每一种分类都会有不同的税收,例如商品包括食品、衣服、书等等,奢侈品会征收奢侈品税,香烟征收烟草税等等
代码结构:
商品Goods类:
税收Tax类:
分类:
分类器:
测试:
这种方法看起来不像是状态模式的,但其实思想还是最基本的状态模式思想。
状态切换器中自己维护了一张状态切换列表,而且不同的状态所执行的操作是一样的。
我们假设商品有多种不同的分类,每一种分类都会有不同的税收,例如商品包括食品、衣服、书等等,奢侈品会征收奢侈品税,香烟征收烟草税等等
代码结构:
商品Goods类:
package com.anvien.practice.state_one; import java.util.HashSet; import java.util.Set; /** * 商品 */ public class Goods { /** 名称 */ private String name; /** 单价 */ private double price; /** 分类集合,一种商品在不同的分类标准下,可能会属于多种分类 */ Set<Category> categories = new HashSet<Category>(); /** * 构造方法 * @param name * 名称 * @param price * 单价 */ public Goods(String name, double price) { this.name = name; this.price = price; } /** * 获取商品名称 * @return * 商品名称 */ public String getName() { return name; } /** * 设置商品名称 * @param name * 商品名称 */ public void setName(String name) { this.name = name; } /** * 获取商品单价 * @return * 商品单价 */ public double getPrice() { return price; } /** * 设置商品单价 * @param price * 商品单价 */ public void setPrice(double price) { this.price = price; } /** * 为商品添加新的分类 * @param category * 新的分类 * @return * 返回添加成功与否 */ public boolean addCategory(Category category) { return this.categories.add(category); } /** * 获取商品的分类集合 * @return * 商品的分类集合 */ public Set<Category> getCategories() { return this.categories; } }
税收Tax类:
package com.anvien.practice.state_one; /** * 税务 * */ public class Tax { /** 名称 */ private String name; /** 税率 */ private double rate; public Tax(String name, double rate) { this.name = name; this.rate = rate; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getRate() { return rate; } public void setRate(double rate) { this.rate = rate; } @Override public String toString() { return "Tax [name=" + name + ", rate=" + rate + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); long temp; temp = Double.doubleToLongBits(rate); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Tax other = (Tax) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (Double.doubleToLongBits(rate) != Double .doubleToLongBits(other.rate)) return false; return true; } }
分类:
package com.anvien.practice.state_one; import java.util.HashSet; import java.util.Set; /** * 商品类别 * */ public class Category { /** 当前类别所包含的商品关键字集合,即商品中包含列表中的某一项关键字的话,商品就属于这种类别的。*/ protected Set<String> contentSet = new HashSet<String>(); /** 当前类别所包含的税收集合。*/ protected Set<Tax> taxSet = new HashSet<Tax>(); /** * 商品执行分类操作的启动方法 * @param classifier * 将要对商品进行分类的分类器 */ public void classify(Classifier classifier) { if(contentSet.contains(classifier.getGoods().getName()) || classifier.isLastCategory()) { classifier.getGoods().addCategory(classifier.getCurrentCategory()); } else { classifier.classify(); } } /** * 设置当前类别的内容关键字列表 * @param list * 内容关键字列表 */ public void setContentSet(Set<String> set) { this.contentSet = set; } /** * 获取当前类别的内容关键字列表 * @return * 内容关键字列表 */ public Set<String> getContentSet() { return this.contentSet; } /** * 向当前税收集合中添加一种新的税收 * @param tax * 新的税收 * @return * 返回税收添加成功与否 */ public boolean addTax(Tax tax) { return this.taxSet.add(tax); } /** * 获取当前类别的税收集合 * @return * 税收集和 */ public Set<Tax> getTaxSet() { return taxSet; } }
分类器:
package com.anvien.practice.state_one; import java.util.ArrayList; import java.util.List; /** * 分类器, 用于检查当前商品在指定分类集合中的所属情况 * */ public class Classifier { private Goods goods; private List<Category> categoryList; int indicator = -1; /** * 构造方法 * @param categoryList * 分类集合 * 注意集合中的最后一项分类为默认分类, * 即商品都不属于集合中的前面分类时,会被归纳为最后一个分类 */ public Classifier(List<Category> categoryList) { this.categoryList = categoryList; } /** * 构造方法 * @param categorys * 分类集合 * 注意集合中的最后一项分类为默认分类, * 即商品都不属于集合中的前面分类时,会被归纳为最后一个分类 */ public Classifier(Category... categorys) { this.categoryList = new ArrayList<Category>(); for(Category c : categorys) { this.categoryList.add(c); } } /** * 返回分类器正在处理的商品 * @return * 返回分类器当前执行分类的商品 */ public Goods getGoods() { return goods; } /** * 设置分类器将要执行分类的商品 * @param goods * 将要执行分类的商品 */ public void setGoods(Goods goods) { this.goods = goods; this.indicator = -1; } /** * 获取分类集合 * @return * 分类集合 */ public List<Category> getCategoryList() { return categoryList; } /** * 设置分类集合 * @param categoryList * 分类集合 */ public void setCategoryList(List<Category> categoryList) { this.categoryList = categoryList; } /** * 返回分类器当前得到的类别 * @return * 当前得到的类别 */ public Category getCurrentCategory() { if(this.categoryList == null || this.indicator > this.categoryList.size()-1) { return null; } return this.categoryList.get(this.indicator); } /** * 返回分类器是否已经在检查最后一种类别 * @return * 是否已经在检查最后一种类别 */ public boolean isLastCategory() { if(this.categoryList == null || this.categoryList.size() < 1 || this.indicator >= this.categoryList.size()-1) { return true; } return false; } /** * 分类器执行类别检查的启动方法 */ public void classify() { this.indicator++; getCurrentCategory().classify(this); } }
测试:
package com.anvien.practice.state_one; public class Main { public static void main(String[] args) { Goods book = new Goods("notebook", 5.0); Goods food = new Goods("food", 12); Tax foodTax = new Tax("food tax", 0.1); Category foodCategory = new Category(); foodCategory.addTax(foodTax); Tax bookTax = new Tax("book tax", 0.2); Category bookCategory = new Category(); bookCategory.addTax(bookTax); Category otherCategory = new Category(); Classifier clsfr = new Classifier(foodCategory, bookCategory, otherCategory); clsfr.setGoods(food); clsfr.classify(); clsfr.setGoods(book); clsfr.classify(); } }
这种方法看起来不像是状态模式的,但其实思想还是最基本的状态模式思想。
相关文章推荐
- 课堂例子验证
- (记录前面算过的后面仍然会用的数减小复杂度)A - AC Me
- Java常用的设计模式09:单例模式的强化(控制实例个数n)
- Myeclipse8.5 里复制粘贴(ctr c ctr v)卡的解决方法
- Linux下 SVN使用
- java学习筆記二。
- volatile关键字解读
- Linux常见命令
- ListView中ConvertView和ViewHolder
- ListView中ConvertView和ViewHolder
- 用递归和穷举法实现的循环赛赛程生成算法
- 算术运算符
- 【PAT】1017. Queueing at Bank (25)
- ALM工具使用流程(一)
- 使用DatePickerDialog和TimePickerDialog实现日期和时间选择对话框
- 1034. 有理数四则运算(20)
- bzoj1455: 罗马游戏
- Git 命令详解
- Java中的Random()函数
- 面向对象