Groovy探索之Decorate模式

                                    Groovy探索之Decorate模式
 
 
Decorate模式是Java编程中比较常用的一种模式,有关Decorate模式的基本知识,如概念、使用场合以及如何使用,请大家查看相关文档。本文所要关注如何在Groovy语言中实现Decorate模式,以及这种实现与Java语言实现的区别,使得我们更加深入的理解Groovy语言的动态性,同时学会在Groovy语言中使用Decorate模式。
说到Decorate模式,一个最最常用的例子是咖啡的例子。下面我们来看看在Java语言中怎么实现这个例子的。
首先是一个接口,接口是Java语言面向对象的基础:
public interface Coffee {
   
        public void descript();
 
}
 
为了例子的简单性,我让Coffee接口只有一个方法。然后,我们要实现原咖啡类:
public class OriginCoffee implements Coffee {
 
        public void descript() {
           System. out .print( "Coffee" );
 
        }
}
 
接着,我们来实现加冰的咖啡:
public class IceCoffee implements Coffee {
   
        private Coffee coffee ;
        public IceCoffee(Coffee coffee)
        {
           this . coffee = coffee;
        }
        public void descript() {
           this . coffee .descript();
           System. out .print( ",with ice" );
 
        }
}
 
看到了上面的两个类 OriginCoffee IceCoffee ,可以看出在 Java 语言中实现 Decorate 模式的一般方法,在此我们就不多说了。
下面是加奶咖啡的实现:
public class MilkCoffee implements Coffee {
 
        private Coffee coffee ;
   
        public MilkCoffee(Coffee coffee)
        {
           this . coffee = coffee;
        }
 
        public void descript() {
           this . coffee .descript();
           System. out .print( ",with Milk" );
        }
}
 
下面,我们来看看 Decorate 模式的客户端实现,首先我们要加奶咖啡:
       Coffee coffee = new MilkCoffee( new OriginCoffee());
    coffee.descript();
 
运行结果为:
Coffee,with Milk
 
如果我们要加奶又加冰的咖啡:
Coffee coffee = new MilkCoffee( new IceCoffee( new OriginCoffee()));
    coffee.descript();
 
运行结果为 :
Coffee,with ice,with Milk
 
在上面的例子中,我们用 Java 实现了一个 Decorate 模式,那么同样的例子在 Groovy 语言又是怎么实现的呢?
我们知道,基于 Groovy 语言的动态性,在很多时候都可以省略接口,在实现 Decorate 模式的时候也一样。
首先来看我们的原咖啡的实现:
class OriginCoffee {
   public descript()
  {
          print 'Coffee'
  }
}
 
没有接口,只有一个方法,很简单。下面是冰咖啡的实现:
class IceCoffee {
    private delegate;
    public IceCoffee(delegate)
    {
       this .delegate = delegate
    }
 
      public descript()
     {
         this .delegate.descript()
         print ',with Ice'
     }
 
}
 
也很简单,基于 Groovy 语言的动态性,我们可以直接编写形如“ this .delegate.descript() ”这样的代码,而在 Java 语言中,我们必须借助接口来实现。
同理来实现加奶咖啡:
class MilkCoffee {
 
    private delegate;
   
    public MilkCoffee(delegate)
    {
       this .delegate = delegate
    }
 
      public descript()
     {
         this .delegate.descript()
         print ',with Milk'
     }
 
}
 
客户端的使用和 Java 语言一样:
      def coffee = new MilkCoffee( new IceCoffee( new OriginCoffee()))
     
 coffee.descript()
 
运行结果为:
Coffee,with Ice,with Milk
 
上面,我们就使用Groovy语言实现了一个最简单的Decorate模式,一切都很简单,也很好理解。如果我们的咖啡复杂一点,比如还要实现计算价格的功能,比如下面的原咖啡:
class OriginCoffee {
   
    float payMount
   
    public pay()
    {
       this .payMount = 2
       return payMount
    }
   
    public printPay()
    {
       println "Total pay mount: ${this.payMount}"
    }
 
      public descript()
     {
         print 'Coffee'
     }
 
}
 
这个类有三个方法:“ descript ”用来描述咖啡种类;“ pay ”用来计算价格;“ printPay ”用来打印咖啡的价格。那么我们该怎么实现加冰的咖啡呢?
当然,我们依然可以沿用上面的方法,其实现如下:
class IceCoffee {
 
    float payMount
   
    private delegate;
   
    public IceCoffee(delegate)
    {
       this .delegate = delegate
    }
   
    public pay()
    {
       this .payMount = this .delegate.pay()+ 0 . 5
       return this .payMount
    }
   
    public printPay()
    {
       println this .payMount
    }
 
      public descript()
     {
         this .delegate.descript()
           print ',with Ice'
     }
}
 
这次实现 Decorate 模式的一般实现模式。我曾经说过,设计模式通过解耦来取得的代码的扩展性,同时也带来了编码的繁琐性。如上面的 IceCoffee 类,需要同时实现三个方法,随着代码的扩展,后面的 MilkCoffee 类、 SugarCoffee 类,都需要同时实现以上的三个方法,十分的繁琐。
Groovy 语言中,结合 MOP 编程,我们还可以对上面的繁琐代码进行进一步的简化,请看下面的 IceCoffee 类:
class IceCoffee {
 
    float payMount
   
    private delegate;
   
    public IceCoffee(delegate)
    {
       this .delegate = delegate
    }
   
    def invokeMethod(String name,args)
    {
       if (name == 'pay' )
       {
           this .payMount = this .delegate.pay()+ 0 . 5
           return this .payMount
       }
       else if (name == 'descript' )
       {
           this .delegate.descript()
           print ',with Ice'
       }
       else
       {
           println this .payMount
       }
    }
 
}
 
不错,又是“ invokeMethod ”方法,让我们在一个方法里把三个功能一起实现,达到简化编码的目的。下面是加奶的咖啡实现:
class MilkCoffee {
    float payMount
    private delegate;
    public MilkCoffee(delegate)
    {
       this .delegate = delegate
    }
   
    def invokeMethod(String name,args)
    {
       if (name == 'pay' )
       {
           this .payMount = this .delegate.pay()+ 1
           return this .payMount
       }
       else if (name == 'descript' )
       {
           this .delegate.descript()
           print ',with Milk'
       }
       else
       {
           println this .payMount
       }
    }
}
 
最后,我们来看看客户端:
      def coffee = new MilkCoffee( new IceCoffee( new OriginCoffee()))
     coffee.descript()
      println ''
     coffee.pay()
 coffee.printPay()
 
打印结果为:
Coffee,with Ice,with Milk
3.5
 
 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值