假设我们要在一个商品显示对象中放入商品对象的任何一个属性
商品显示类的定义如下
代码语言:javascript复制@Data
public class ProductShow {
private String title;
}
商品类的定义如下
代码语言:javascript复制@AllArgsConstructor
@Data
public class Product {
private String name;
private BigDecimal amount;
private LocalDate date;
}
商品工厂类定义如下
代码语言:javascript复制public class ProductFactory {
public static Product createProduct() {
Product product = new Product("football",new BigDecimal("36.4"), LocalDate.now());
return product;
}
}
显示的枚举Tag定义如下
代码语言:javascript复制public enum Tag {
Name,Amount,Date;
}
我们写一个管理类来打印商品显示类要显示商品的哪个属性
代码语言:javascript复制public class ProductManager {
public static ProductShow showProduct(Tag tag) {
Product product = ProductFactory.createProduct();
ProductShow productShow = new ProductShow();
if (tag.equals(Tag.Name)) {
productShow.setTitle(product.getName());
}else if (tag.equals(Tag.Amount)) {
productShow.setTitle(product.getAmount().toString());
}else if (tag.equals(Tag.Date)) {
productShow.setTitle(product.getDate().toString());
}
return productShow;
}
public static void main(String[] args) throws Exception {
ProductShow show = ProductManager.showProduct(Tag.Name);
System.out.println(show.getTitle());
}
}
运行结果:
football
这里我们可以看到很多if...else if....else if,如果这里商品的属性非常多,就会不断的增加else if,这显然不是一个好主意,增加了强耦合。
现在我们把它进行拆分解耦,由标签来决定显示哪一个属性。
我们的策略接口为
代码语言:javascript复制public interface ShowProduct {
public ProductShow showProduct(Product product);
}
各自的实现类分别为
代码语言:javascript复制@NoArgsConstructor
public class ShowName implements ShowProduct{
@Override
public ProductShow showProduct(Product product) {
ProductShow productShow = new ProductShow();
productShow.setTitle(product.getName());
return productShow;
}
}
代码语言:javascript复制@NoArgsConstructor
public class ShowAmount implements ShowProduct {
@Override
public ProductShow showProduct(Product product) {
ProductShow productShow = new ProductShow();
productShow.setTitle(product.getAmount().toString());
return productShow;
}
}
代码语言:javascript复制@NoArgsConstructor
public class ShowDate implements ShowProduct {
@Override
public ProductShow showProduct(Product product) {
ProductShow productShow = new ProductShow();
productShow.setTitle(product.getDate().toString());
return productShow;
}
}
我们将枚举Tag做一下修改
代码语言:javascript复制public enum Tag {
Name("com.guanjian.product.ShowName"),
Amount("com.guanjian.product.ShowAmount"),
Date("com.guanjian.product.ShowDate");
private final String value;
private Tag(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
定义一个标签
代码语言:javascript复制@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ShowTag {
Tag value();
}
给商品显示类的title字段打上标签
代码语言:javascript复制@Data
public class ProductShow {
@ShowTag(value = Tag.Amount)
private String title;
}
这个时候我们在商品管理类中添加方法
代码语言:javascript复制public static ProductShow showProduct() throws Exception {
Product product = ProductFactory.createProduct();
ProductShow productShow = new ProductShow();
Field title = productShow.getClass().getDeclaredField("title");
ShowTag tag = title.getAnnotation(ShowTag.class);
Object showProduct = Class.forName(tag.value().getValue()).newInstance();
productShow = ((ShowProduct) showProduct).showProduct(product);
return productShow;
}
修改main方法
代码语言:javascript复制public static void main(String[] args) throws Exception {
ProductShow show = ProductManager.showProduct();
System.out.println(show.getTitle());
}
运行结果:
36.4
这样我们只需要替换商品显示类的title字段的标签的枚举value,就可以显示商品的哪一个属性了。根据这一思想以后还需要做进一步的扩展,考虑多级分层。