假設咱們要在一個商品顯示對象中放入商品對象的任何一個屬性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,就能夠顯示商品的哪個屬性了。根據這一思想之後還須要作進一步的擴展,考慮多級分層。