liuqiang5151

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  0 Posts :: 23 Stories :: 1 Comments :: 0 Trackbacks
      看过HeadFirst设计模式这本书,感觉对OO的直觉更深了一步。真心推荐朋友们研究一下这本书,它不像四人帮写的那本经典版本,看了就想睡觉。而是犹如讲故事一样带领你在设计模式的国度里畅游。
        今天来说一些设计模式的原则,虽然有的时候在工作中用不上,但是理解了这些原则对培养你的面向对象的思想会有很大帮助的。当你带着这些经验去读一些源码的时候,会情不自禁的联想起这些原则,那种感觉就好像麦当劳。
      还是举个例子来说吧,让我们来设计一个门的类Door,我们先抽象出两个最直接的方法,open, close。
public abstract class Door {
    
public abstract void open();
    
public abstract void close();
    
public final void info() {
        System.out.println(
"I'm a door");
    }

}
首先我们想到了继承,因为我们是OO程序员嘛,然后分别产生两个子类ChinaDoor ,AmericaDoor
public class ChinaDoor extends Door {
    
public void open() {
        System.out.println(
"China open");
    }

    
public void close() {
        System.out.println(
"China close");
    }

}

public class AmericaDoor {
    
public void open() {
        System.out.println(
"America open");
    }

    
public void close() {
        System.out.println(
"America close");
    }

}

分别提供不同的开关方式。看样一切都还算顺利......
可怕的事情发生了,现在要加入报警功能,于是在基类写个alarm方法,子类纷纷重写这个方法。但是并不是所有的门都有报警功能,于是我们想到了空实现。
但是这样设计并不是很好,继承的坏处体现出来了,于是我们想到了接口。把alarm行为从基类中分离出去,定义为接口,这样让有报警功能的门实现Alarm接口,没有报警功能的类就不实现接口。但是这似乎不是万全之策。
public interface Alarm {
    
void doAlarm();
}
虽然这样可以避免上面的尴尬,但是这样却不能得到代码的复用,假如我有1000个类报警的行为都相同,那我还要让这1000个类都去实现这个接口吗。
我们可以设计出一些报警行为的类
public class SoftAlarm implements Alarm {
    @Override
    
public void doAlarm() {
        
// TODO Auto-generated method stub
        System.out.println("soft alarm");
    }

}


public class SongAlarm implements Alarm {
    @Override
    
public void doAlarm() {
        
// TODO Auto-generated method stub
        System.out.println("song alarm");
    }

}

现在我们的基类可以这样设计
public abstract class Door {
    
private Alarm alarm;
    
    
public void setAlarm(Alarm alarm) {
        
this.alarm = alarm;
    }

    
public abstract void open();
    
public abstract void close();
    
public final void performAlarm() {
        alarm.doAlarm();
    }

    
public final void info() {
        System.out.println(
"I'm a door");
    }

}

这里保存着一个报警类型的引用,于是这里又引出了一个原则,针对接口编程,不要针对实现编程。这样我们可以很方便的利用多态来调用相应的方法。
好了,我们的门可以正式上线了
public class TestDoor {
    
public static void main(String[] args) {
        
// TODO Auto-generated method stub
        Door door = new ChinaDoor();
        Alarm alarm 
= new SoftAlarm();
        door.setAlarm(alarm);
        door.open();
        door.performAlarm();
    }

}

运行结果
China open
soft alarm
大家可以看到,在运行的时候动态的传入报警的行为,可以利用多态调用相应的方法,这就是组合的威力。
好了,我们重头看一下,因为有了alarm行为,我们不能用继承来实现了,所以我们把alarm行为抽象了出来。这就是把变化的部分抽象出来,然后利用组合(可以有各种各样的接口)在运行时动态的赋予其行为,因为我们传进去的参数是接口类型,所以我们根本不用管里面是如何运作的。多酷啊。现在你可以在加一个行为自动开关行为autoOpen,利用组合在运行时赋予其职能。gogogo
posted on 2008-05-29 18:16 刘强 阅读(178) 评论(0)  编辑  收藏 所属分类: 设计模式

只有注册用户登录后才能发表评论。


网站导航: