假设我们要在一个商品显示对象中放入商品对象的任何一个属性
商品显示类的定义如下
@Datapublic classProductShow {
privateString title;}
商品类的定义如下
@AllArgsConstructor@Datapublic classProduct {
privateString name;privateBigDecimal amount;privateLocalDate date;}
商品工厂类定义如下
public classProductFactory {
public staticProduct createProduct() {
Product product = newProduct("football",newBigDecimal("36.4"),LocalDate.now());returnproduct;}
}
显示的枚举Tag定义如下
public enumTag {
Name,Amount,Date;}
我们写一个管理类来打印商品显示类要显示商品的哪个属性
public classProductManager {
public staticProductShow showProduct(Tag tag) {
Product product = ProductFactory.createProduct();ProductShow productShow = newProductShow();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());}
returnproductShow;}
public static voidmain(String[] args) throwsException {
ProductShow show = ProductManager.showProduct(Tag.Name);System.out.println(show.getTitle());}
}
运行结果:
football
这里我们可以看到很多if...else if....else if,如果这里商品的属性非常多,就会不断的增加else if,这显然不是一个好主意,增加了强耦合。
现在我们把它进行拆分解耦,由标签来决定显示哪一个属性。
我们的策略接口为
public interfaceShowProduct {
publicProductShow showProduct(Product product);}
各自的实现类分别为
@NoArgsConstructorpublic classShowName implementsShowProduct{
@OverridepublicProductShow showProduct(Product product) {
ProductShow productShow = newProductShow();productShow.setTitle(product.getName());returnproductShow;}
}
@NoArgsConstructorpublic classShowAmount implementsShowProduct {
@OverridepublicProductShow showProduct(Product product) {
ProductShow productShow = newProductShow();productShow.setTitle(product.getAmount().toString());returnproductShow;}
}
@NoArgsConstructorpublic classShowDate implementsShowProduct {
@OverridepublicProductShow showProduct(Product product) {
ProductShow productShow = newProductShow();productShow.setTitle(product.getDate().toString());returnproductShow;}
}
我们将枚举Tag做一下修改
public enumTag {
Name("com.guanjian.product.ShowName"),Amount("com.guanjian.product.ShowAmount"),Date("com.guanjian.product.ShowDate");private finalString value;privateTag(String value) {
this.value= value;}
publicString getValue() {
return this.value;}
}
定义一个标签
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public@interfaceShowTag{
Tag value();}
给商品显示类的title字段打上标签
@Datapublic classProductShow {
@ShowTag(value= Tag.Amount)
privateString title;}
这个时候我们在商品管理类中添加方法
public staticProductShow showProduct() throwsException {
Product product = ProductFactory.createProduct();ProductShow productShow = newProductShow();Field title = productShow.getClass().getDeclaredField("title");ShowTagtag = title.getAnnotation(ShowTag.class);Object showProduct = Class.forName(tag.value().getValue()).newInstance();productShow = ((ShowProduct) showProduct).showProduct(product);returnproductShow;}
修改main方法
public static voidmain(String[] args) throwsException {
ProductShow show = ProductManager.showProduct();System.out.println(show.getTitle());}
运行结果:
36.4
这样我们只需要替换商品显示类的title字段的标签的枚举value,就可以显示商品的哪一个属性了。根据这一思想以后还需要做进一步的扩展,考虑多级分层。