设计模式— 认识

设计模式,对大家来说都不陌生,但是里面的东西和武功一样,悟 了就简单,不然你永远可以知道,但是使用的都是皮毛,下面我借Head First 书里面的,给想我一样的新手,开拓一下思维,了解为什么要使用设计模式:

 

假设,现在要做一套模拟鸭子的游戏,我该如何设计?

我们先设计一个鸭子的超类(Superclass),然后让各种鸭子都集成这个类,当然,里面定义了一些公共方法,鸭子都有的。

public class Duck {
	
	public void quack() {// 呱呱叫}
	
	public void swin(){// 游泳}
	// 其他方法..
}

 

另外两个类:MallerDuck 和 RedheadDuck ,实现自己的外观

public class MallarDuck extends Duck{
	public void display(){
		// 绿毛鸭
	}
}

 

public class RedheadDuck extends Duck{
	public void display(){
		// 红毛鸭
	}
}

 

OK,那么现在公司要求,鸭子会飞。可能你说简单嘛,给父类加上 fly() 方法

public class Duck {
	public void quack() {
		// 呱呱叫
	}
	public void swin(){
		// 游泳
	}
	public void fly(){
		// 飞
	}
}

 

但是当进行测试的时候,发现很多玩具鸭子,也在飞...,老板很尴尬。当初客户也没说有玩具鸭子啊?但是开发的明白一点,需求是可变的,它永远是追寻更大的利益化,只要能让使用的人满意,没办法。

 

仔细一样,可以进行方法覆盖,那么玩具鸭子有自己的行为,总飞不起来了嘛

public class DecoyDuck extends Duck{
	public void quack() {
		// 玩具鸭子,唧唧叫
	}
	public void swin(){
		// 游泳
	}
	public void fly(){
		// 什么都不做,不能飞
	}
        public void display(){
		// 这是玩具鸭
	}
}

 

现在又接到消息说,为了创新,可能会出现各种不同的鸭子,但是很多fly()等方法会一样,那么不是要重复的去写很多fly()和quart()的方法吗,会写很多,痛苦!这时候我想到接口,为特殊的行为制定接口,需要才去实现。

public interface Quackable {
	public void quack();
}

public interface Flyable {
	public void fly();
}

// 等等

 然后其他去实现接口

public class MallarDuck implements Flyable,Quackable{
	public void display(){
		// 绿毛鸭
	}
	@Override
	public void fly() {
	}

	@Override
	public void quack() {
	}
}
// 其他的类似

 

但是 这样还是觉得并没有实质的进展,如果 有N多的鸭子,那么得重复多少代码啊!

这让我们引出的一个真理:软件开发中,唯一不变得是变化。

我想起了经常说的一句话:设计是因为未来而存在

 

此时的代码无论是重用性和复杂度 以及修改 都不好,我们引出一个很重要的设计原则:

找出程序中可能需要变化的部分,把他们独立出来,进行封装,不要和那些不需要变化的代码放一起。结果就是可以轻易的改动或者扩展 要变化的部分,而不引起其他不需要变化的部分。

 

为了达到代码重用,又方便扩展的情况,我先把Duck 不变得 swim() 独立出来,然后把fly() 和 quack ()这些会变得行为拿出来,看看代码怎么做:

 

public class Duck {
	public void swin(){
		// 游泳,共有的部分
	}
}

public interface FlyBehaviour {
        // 飞 这个行为的接口,下面同理
	public void fly();
}
public interface QuackBehaviour {
        // 叫的接口
	public void quack();
}

public class FlyWithWing implements FlyBehaviour{
	@Override
	public void fly() {
		// 会飞的 鸭子
		// 具体实现,可以共用的代码,下面同理
	}
}
public class FlyNoWay  implements FlyBehaviour{
	@Override
	public void fly() {
		// 不会飞 的鸭子
	}
}
// 下面 quck 同理

public class QuackOne implements QuackBehaviour{
	@Override
	public void quack() {
		// 普通鸭子 呱呱叫
	}
}
public class QuackTwo implements QuackBehaviour {
	@Override
	public void quack() {
		// 橡皮鸭子  唧唧叫
	}
}

 

OK,现在的代码,灵活性就更高了。比如我现在可能会添加更多的鸭子,那么无论是会飞的,不会飞的,这些代码是可以重用的,如果需要添加 另外的叫声,我们同样可以创建一个新的QuackThree 去实现接口,也是可以扩展的,现在的代码是不是好很多了呢?

 

说了这么多,我们初略分析一下, 拿到需求的时候,不要简单的直接开始写代码,为了程序的灵活性,我们应当做一些考虑,这样为我们以后减少工作量做准备。因为程序时间长的部分是维护,开始时间最短,那么我们应该这样去思考,形成习惯,慢慢代码就会好很多了。

 

 

 

猜你喜欢

转载自greemranqq.iteye.com/blog/1827744