状态模式的具体实现 情景三

来源:互联网 发布:java 高性能tcp服务器 编辑:程序博客网 时间:2024/05/27 14:13

这篇中,我们将看到一种不同于前两篇的状态模式设计方法。

状态切换器中自己维护了一张状态切换列表,而且不同的状态所执行的操作是一样的。

我们假设商品有多种不同的分类,每一种分类都会有不同的税收,例如商品包括食品、衣服、书等等,奢侈品会征收奢侈品税,香烟征收烟草税等等

代码结构:


商品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;}@Overridepublic String toString() {return "Tax [name=" + name + ", rate=" + rate + "]";}@Overridepublic 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;}@Overridepublic 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();}}


这种方法看起来不像是状态模式的,但其实思想还是最基本的状态模式思想。



0 0