类的递归和组合模式
2008-03-11 15:39
141 查看
类的递归和组合模式
递归算法是大家非常熟悉的一种算法。如著名的菲波拉契数列:输入数列的前两项,以后的每一项都是它的前两项之和。现在我们要求该数列的第N(N>0)位的数是多少。对于这个问题,我们可以很轻松的给出下面的算法:
public int getResult(int first,int second,int number)
{
if(number==1) return first;
else if(number==2) return second;
else if(number>2) return getResult(first,second,number-2)+getResult(first,second,number-1);
//输入有误,返回错误代码
else return –1;
}
这就是一个典型的递归算法。这种算法的一个好处是客户端在使用该方法时,不管是N为1或2或者以上,都使用同一个方法,简化了客户端的调用。
关于递归的话题,在这里我们也不想多说,我们却有兴趣将这个问题扩展开来说:我们知道,类其实是数据和对数据的算法放在一起的封装,既然算法有递归的问题,如上面所示;那么数据是不是也有递归的问题呢?如果答案是肯定的的话,那么该算法和数据加在一起不就是类了,那么类也应该有递归的问题了?
真的是这样吗?
我们来看这样一个实际的问题:
我们会经常去买一些光盘,如果买得多的话,就会需要一个光盘盒。假设商家需要这么一个售卖系统,卖给客户商品需要打印商品信息和应付款项。
这里我们分析一下,需要两个类:光盘类和光盘盒类。每一类都有相同的两个方法,一个打印商品信息、一个给出应付款项。
然后我们在客户端调用如下:
如果客户买光盘,则调用光盘类的两个方法;
如果客户买光盘盒,则调用光盘盒类的两个方法;
如果客户买装有光盘的光盘盒,则调用两者之和。
以上是我们的一个常规的思路。对于这样的客户端调用,我们会发现它的很多弱点:第一是不符合依赖颠倒原则,客户端强烈的依赖两个具体的类,这样,如果商家再增加一种新的商品,则需要修改客户端;第二是将对商品的判断放在了客户端,不符合单一职责原则。
但是我们看看客户端对两个类的调用方法,就会发现它很符合递归算法的一般逻辑,只不过这里不是简单方法,而是类。那么我们对于这样的类,也会不会有所谓的递归算法呢?
为什么需要递归算法?我们先不考虑太多,递归算法有一个明显的好处就是客户端调用的接口是统一的,而不需要做if…else…判断,这简化了客户端的调用。
这里所谓的类的递归,其实就是组合模式。下面我们来看看组合模式是怎么来解决上面的问题的:
首先我们来写一个接口,这是绝大多数的模式需要做的,它是为了满足面向对象的基本原则的依赖颠倒原则,而该原则的目的是为了使用多态性:
public interface Equipment
{
public void description();
public double getCount();
}
这个接口有两个目的:对商品进行描述和取得应付款项。
接着我们来看光盘类的实现:
public class Disk implements Equipment {
public void description() {
System.out.println("disk...");
}
public double getCount() {
return 1.2;
}
}
这个类很简单,没有什么好说的。下面来看光盘盒类:
import java.util.ArrayList;
import java.util.List;
public class Classic implements Equipment {
private List disks = new ArrayList();
public void add(Equipment equipment)
{
disks.add(equipment);
}
public void description() {
//先给出对盒部分的描述
System.out.println("classic...");
//然后是对盘部分的描述,两者加起来就是对带盘的光盘盒的描述
for(int i=0;ird?ld:rd)+1;
}
}
递归算法是大家非常熟悉的一种算法。如著名的菲波拉契数列:输入数列的前两项,以后的每一项都是它的前两项之和。现在我们要求该数列的第N(N>0)位的数是多少。对于这个问题,我们可以很轻松的给出下面的算法:
public int getResult(int first,int second,int number)
{
if(number==1) return first;
else if(number==2) return second;
else if(number>2) return getResult(first,second,number-2)+getResult(first,second,number-1);
//输入有误,返回错误代码
else return –1;
}
这就是一个典型的递归算法。这种算法的一个好处是客户端在使用该方法时,不管是N为1或2或者以上,都使用同一个方法,简化了客户端的调用。
关于递归的话题,在这里我们也不想多说,我们却有兴趣将这个问题扩展开来说:我们知道,类其实是数据和对数据的算法放在一起的封装,既然算法有递归的问题,如上面所示;那么数据是不是也有递归的问题呢?如果答案是肯定的的话,那么该算法和数据加在一起不就是类了,那么类也应该有递归的问题了?
真的是这样吗?
我们来看这样一个实际的问题:
我们会经常去买一些光盘,如果买得多的话,就会需要一个光盘盒。假设商家需要这么一个售卖系统,卖给客户商品需要打印商品信息和应付款项。
这里我们分析一下,需要两个类:光盘类和光盘盒类。每一类都有相同的两个方法,一个打印商品信息、一个给出应付款项。
然后我们在客户端调用如下:
如果客户买光盘,则调用光盘类的两个方法;
如果客户买光盘盒,则调用光盘盒类的两个方法;
如果客户买装有光盘的光盘盒,则调用两者之和。
以上是我们的一个常规的思路。对于这样的客户端调用,我们会发现它的很多弱点:第一是不符合依赖颠倒原则,客户端强烈的依赖两个具体的类,这样,如果商家再增加一种新的商品,则需要修改客户端;第二是将对商品的判断放在了客户端,不符合单一职责原则。
但是我们看看客户端对两个类的调用方法,就会发现它很符合递归算法的一般逻辑,只不过这里不是简单方法,而是类。那么我们对于这样的类,也会不会有所谓的递归算法呢?
为什么需要递归算法?我们先不考虑太多,递归算法有一个明显的好处就是客户端调用的接口是统一的,而不需要做if…else…判断,这简化了客户端的调用。
这里所谓的类的递归,其实就是组合模式。下面我们来看看组合模式是怎么来解决上面的问题的:
首先我们来写一个接口,这是绝大多数的模式需要做的,它是为了满足面向对象的基本原则的依赖颠倒原则,而该原则的目的是为了使用多态性:
public interface Equipment
{
public void description();
public double getCount();
}
这个接口有两个目的:对商品进行描述和取得应付款项。
接着我们来看光盘类的实现:
public class Disk implements Equipment {
public void description() {
System.out.println("disk...");
}
public double getCount() {
return 1.2;
}
}
这个类很简单,没有什么好说的。下面来看光盘盒类:
import java.util.ArrayList;
import java.util.List;
public class Classic implements Equipment {
private List disks = new ArrayList();
public void add(Equipment equipment)
{
disks.add(equipment);
}
public void description() {
//先给出对盒部分的描述
System.out.println("classic...");
//然后是对盘部分的描述,两者加起来就是对带盘的光盘盒的描述
for(int i=0;ird?ld:rd)+1;
}
}
相关文章推荐
- 类的递归和组合模式
- 类的递归和组合模式
- 类的递归和组合模式
- Composite 组合模式 部分-整体 树 递归
- 类的递归和组合模式
- 《javascript设计模式与开发实践》阅读笔记(10)—— 组合模式
- 设计模式之组合模式java实现
- 接口型模式之Composite(组合)模式
- 由模式谈面向对象的原则之多用组合、少用继承
- STL源码剖析 05 基础-CRTP奇特的递归模式模板 子类作为父类的模板参数
- 设计模式---->组合/聚合复用原则
- Java设计模式之十四(组合模式)
- 设计模式一日一练:组合模式(Composite)
- 代码设计模式之组合模式(Composite)
- 设计模式_组合模式
- java设计模式之组合模式
- 设计模式-组合模式
- Java设计模式之组合模式
- 设计模式之组合模式
- 组合模式