[关闭]
@linux1s1s 2019-02-18T10:06:37.000000Z 字数 2816 阅读 1841

Java 设计模式 - 装饰模式

Java设计模式


前一节已经介绍了Java设计模式 -- 适配器/装饰器模式 ,因为一笔带过,所以这里再补充一下。

关于装饰器模式,在具体的Android源码中 比较常见,一般都是以Wrapper作为结尾

比较典型的是ContextWrapper,这里篇幅有限,暂不做解析,文章后面会出给UML图做个简单理解。

我们不从最基本的装饰器模式概念入手,先来看问题好了。

提出问题

假如 有以下海关入关通用处理方法

  1. public class ShangHaiCustoms {
  2. public void procedure() {
  3. System. out.println("ShangHai common procedure!" );
  4. }
  5. }
  6. public class BeiJingCustoms{
  7. public void procedure() {
  8. System. out.println("BeiJing customs procedure!" );
  9. }
  10. }

现在我们需要新加入需求,原先的处理流程不变,但是需要加入security checkskeep on record, 这两个部分分别位于原先方法的前面和后面,如果我们不加任何思考可以直接简单粗暴

  1. public void securityCheck() {
  2. System. out.println("SeafoodCustoms security checks!" );
  3. }
  4. public void keepOnRecord() {
  5. System. out.println("SeafoodCustoms keep on record!" );
  6. }

直接把这两个方法加在原先类的合适位置即可,这个修改不会带来多大的负面影响,假如我们区分 食品和海产品的 security checks和keep on record分别都不同, 那么还要修改上面的两个方法 以区分食品和海产品, 如果后续还有什么需求,是不是修改起来比较费劲,因为要不断的修改原先的类,这个明显违背了设计模式对修改封闭原则

下面我们一起来看看如何对上面的需求做设计

解决方案

先提取接口

  1. public interface Customs {
  2. public void procedure();
  3. }

接着修改原先的两个类如下

  1. public class ShangHaiCustoms implements Customs {
  2. @Override
  3. public void procedure() {
  4. System. out.println("ShangHai common procedure!" );
  5. }
  6. }
  7. public class BeiJingCustoms implements Customs {
  8. @Override
  9. public void procedure() {
  10. System. out.println("BeiJing customs procedure!" );
  11. }
  12. }

接着做个包装类

  1. public class CustomsWrapper implements Customs {
  2. private Customs customs;
  3. public CustomsWrapper(Customs customs) {
  4. this.customs = customs;
  5. }
  6. @Override
  7. public void procedure() {
  8. customs.procedure();
  9. }
  10. }

到这先停一下, 如果对于所有的商品security checks和keep on record都相同, 那么我们直接在这个类中加入上面的securityCheck()和keepOnRecord()即可,这种情况比较简单,也好理解。
如果对于不同品种的商品security checks和keep on record都不相同,该如何处理呢?

很明显我们可以这样做:这里仅仅举普通食品和海产品例子

  1. public class FoodCustoms extends CustomsWrapper {
  2. public FoodCustoms(Customs customs) {
  3. super(customs );
  4. }
  5. @Override
  6. public void procedure() {
  7. // Before do someThing, security checks;
  8. securityCheck();
  9. super.procedure();
  10. // After do someThing, keep on record
  11. keepOnRecord();
  12. }
  13. public void securityCheck() {
  14. System. out.println("FoodCustoms security checks!" );
  15. }
  16. public void keepOnRecord() {
  17. System. out.println("FoodCustoms keep on record!" );
  18. }
  19. }
  20. public class SeaFoodCustoms extends CustomsWrapper {
  21. public SeaFoodCustoms(Customs customs) {
  22. super(customs );
  23. }
  24. @Override
  25. public void procedure() {
  26. // Before do someThing, security checks;
  27. securityCheck();
  28. super.procedure();
  29. // After do someThing, keep on record
  30. keepOnRecord();
  31. }
  32. public void securityCheck() {
  33. System. out.println("SeafoodCustoms security checks!" );
  34. }
  35. public void keepOnRecord() {
  36. System. out.println("SeafoodCustoms keep on record!" );
  37. }
  38. }

然后我们可以在测试用例中体现多态了

  1. public class TestCase {
  2. public static void main(String[] args) {
  3. /*
  4. * ShangHai customs common procedure;
  5. */
  6. commonProcedure();
  7. /*
  8. * ShangHai customs dynamic procedure;
  9. */
  10. dynamicProcedure();
  11. }
  12. private static void dynamicProcedure() {
  13. Customs dyCustoms = new ShangHaiCustoms();
  14. CustomsWrapper dyWrapper = new FoodCustoms(dyCustoms );
  15. dyWrapper.procedure();
  16. }
  17. private static void commonProcedure() {
  18. Customs customs = new ShangHaiCustoms();
  19. CustomsWrapper wrapper = new CustomsWrapper(customs);
  20. wrapper.procedure();
  21. }
  22. }

用个简单的图表示如下:
此处输入图片的描述

附录

上面提及的ContextWrapper结构图
此处输入图片的描述

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注