设计模式与内存分析

【前言】

    通过以前对设计模式的学习和最近软考对设计模式的研究,有的设计模式如果用“内存分析”来辅助,我觉得更加容易理解,下面举职责链模式和装饰模式的例子说明。

【装饰模式】

类图:


装饰模式以“星巴兹咖啡”为例,其类图为:


代码如下:

<span style="font-size:18px;">public abstract class Beverage {  
    String description = "Unknown Beverage";  
      
    public String getDescription() {  
        return description;  
    }  
      
    public abstract double cost();  
} 
</span>

Beverage类很简单,让我们也来实现Condiment(调料)抽象类,也就是装饰者类:

<span style="font-size:18px;">public abstract class CondimentDecorator extends Beverage {  
    public abstract String getDescription();  
      
} 
</span>

现在已经有了基类,让我们开始实现一些饮料吧。别忘了我们需要为具体的饮料设置描述,而且还必须实现cost()方法:

<span style="font-size:18px;">public class Espresso extends Beverage {  
    public Espresso() {  
        description = "Espresso Coffee";  
    }  
      
    @Override  
    public double cost() {  
        return 1.99;  
    }  
}
</span>

饮料类DarkRoast、Decaf、HouseBlend与类Espresso 类似,此处省略。

如果你回头看类图,现在我们已经实现了抽象组件(Beverage),有了具体组件(HouseBlend。。。),也有了抽象装饰者(CondimentDecorator),现在让我们来实现具体装饰者:
<span style="font-size:18px;">public class Mocha extends CondimentDecorator {  
    Beverage beverage;  
      
    public Mocha(Beverage beverage) {  
        this.beverage = beverage;  
    }  
      
    @Override  
    public String getDescription() {  
        return beverage.getDescription() + ", Mocha";  
    }  
    @Override  
    public double cost() {  
        return 0.20 + beverage.cost();  
    }  
}  
</span>

调料类Milk、Soy、Whip与类Mocha类似,此处省略。

下来些客户端代码:

public class StarbuzzCoffee {
    public static void main(String args[]) {
Beverage beverage = new Espresso(); //内存分析从这里开始,对应下图的线1


beverage= new Soy(beverage);  //对应下图的线2,第一个"beverage3"是调料Soy,第二个“ beverage3”是饮料Espresso
beverage = new Mocha(beverage);//对应下图的线3,第一个"beverage3"是调料Mocha,第二个“ beverage3”是调料Soy
beverage = new Whip(beverage);//对应下图的线4,第一个"beverage3"是调料Whip,第二个“ beverage3”是饮料Mocha
System.out.println(beverage.getDescription() 
+ " $" + beverage.cost()); //分析这句代码:运行beverage3.getDescription()方法,从以上三句代码分析,此时的“beverage3”代表的是Whip对象,当你调用Whip的getDescription()方法时,(观看以上Whip具体实现代码),此时”beverage.getDescription()“中的“beverage”代表的是Mocha(这对应着线4),以此类推,最后出现结果:Espresso, Soy, Mocha, Whip 。价格方法也是一样
}
}

运行结果如下:


内存分析图:

【职责链模式】

类图:

 
 

软考例题:

阅读以下说明以及Java程序,将应填入 (n) 处的字句写在答题纸的对应栏内。

【说明】

       已知某企业的采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批,主任可以审批5万元以下(不包括5万元)的采购单,副董事长可以审批5万元至10万元(不包括10万元)的采购单,董事长可以审批10万元至50万元(不包括50万元)的采购单,50万元及以上的采购单就需要开会讨论决定。

       采用责任链设计模式(Chain of Responsibility)对上述过程进行设计后得到的类图如图7-1所示。

<span style="font-size:18px;">class PurchaseRequest {
  public     double Amount;   // 一个采购的金额
  public     int Number;      // 采购单编号
  public     String Purpose;   // 采购目的
}
 
class Approver {      // 审批者类
  public     Approver(){  successor = null;     }
  public     void ProcessRequest(PurchaseRequest aRequest){
              if (successor != null){    successor.(ProcessRequest(aRequest));     }
       }
  public     void SetSuccessor(Approver aSuccesssor){ successor = aSuccesssor; }
  private      (Approver)   successor;
}
 
class Congress extends Approver {   //例会类
  public void ProcessRequest(PurchaseRequest aRequest){
              if(aRequest.Amount >= 500000){ /* 决定是否审批的代码省略 */  }
              else   (super)  .ProcessRequest(aRequest);
       }
}
 
class Director extends Approver {     //主任类
  public void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */    }
}
 
class President extends Approver {    //董事长类
  public     void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */ }
}
 
class VicePresident extends Approver {    副董事长类
  public     void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */ }
}</span>

客户端代码:

public class rs {

       public static void main(String[] args) throws IOException {

              Congress Meeting = new Congress();                           //实例化对象在堆中开辟空间,对应线1。不确定之处:实例化多个子类,有多少个子类实例化就开辟 多少个父类内存空间,如下图中,每个子类中都有一个父类

              President Tammy = new President();                           //对应线2

              VicePresident Sam = new VicePresident();                  //对应线3

              Director Larry = new Director();                                 //对应线4


              // 构造责任链

              Meeting.SetSuccessor(null);                                //对应线8,如果采购单自己处理不了,通过父类里边的审批                                                                                              者引用来指定下一个对象(NULL)来处理。

                  Sam.SetSuccessor(  Tammy  );               //对应线6,如果采购单自己处理不了,通过父类里边的审                                                                                                   批者引用来指定下一个对象(Tammy)来处理。

              Tammy.SetSuccessor(  Meeting  );             //对应线7,如果采购单自己处理不了,通过父类里边的审批                                                                                              者引用来指定下一个对象(Meeting )来处理。

              Larry.SetSuccessor(  Sam  );                  //对应线5,如果采购单自己处理不了,通过父类里边的审批者                                                                                           引用来指定下一个对象(Sam)来处理。

 

              // 构造一采购审批请求              PurchaseRequest aRequest = new PurchaseRequest();

              BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

              aRequest.Amount = Double.parseDouble(br.readLine());

             //对以下这句代码,如果说采购单是50万以上的,这句代码的执行是:Larry(任). ProcessRequest(Sam(副董事长). ProcessRequest(Tammy(董事长). ProcessRequest(Congress(例会). ProcessRequest(aRequest))))

                Larry  .ProcessRequest(aRequest);        // 开始审批

              

              return ;

       }

}

内存分析图:


【总结】

         总之,我觉得刚开始时,模糊的地方通过内存分析,变得很是清晰,希望能对大家有所帮助。

         通过各种方式来学习,来帮助自己了解,这也是知识网的体现。

         








  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 60
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 60
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值