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