假设咱们要在一个商品显示对象中放入商品对象的任何一个属性ide
商品显示类的定义以下this
@Data public class ProductShow { private String title; }
商品类的定义以下spa
@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; }
咱们写一个管理类来打印商品显示类要显示商品的哪一个属性ci
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()); } }
运行结果:get
footballit
这里咱们能够看到不少if...else if....else if,若是这里商品的属性很是多,就会不断的增长else if,这显然不是一个好主意,增长了强耦合。io
如今咱们把它进行拆分解耦,由标签来决定显示哪个属性。class
咱们的策略接口为
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,就能够显示商品的哪个属性了。根据这一思想之后还须要作进一步的扩展,考虑多级分层。