使用策略模式加標籤來解決商品顯示的一級分層
阿新 • • 發佈:2019-05-11
假設我們要在一個商品顯示物件中放入商品物件的任何一個屬性
商品顯示類的定義如下
@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 staticProduct 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,就可以顯示商品的哪一個屬性了。根據這一思想以後還需要做進一步的擴充套件,