设计模式一之策略模式(java)

    这是我看Head first设计模式书籍之后想要总结的知识点,一方面是对自己学习的东西总结和提炼加强自己的理解和记忆,另一方面是给大家简化这本书,方便大家快速了解各种设计模式。

我想提醒大家的是,设计模式只是前人总结的一些经验套路,实际上还是要在开发项目中慢慢体会,不可成为设计模式的中毒患者,强行照搬设计模式的一些规则。


我们这次要讲解的设计模式是策略模式

我们举个栗子:

我们设计了一个鸭子超类(Superclass),并让各种鸭子继承此超类。如果我们要更改需求,需要让鸭子可以飞翔,就在父类中添加了fly()方法,但是后来需求又变化了,我们要增加一个不会飞的鸭子来继承复用鸭子超类的一些方法,这样就产生了不会飞的鸭子飞翔的尴尬画面。

这时候通常大家的思路是:

1.虽然你可在不会飞的鸭子中覆盖父类的fly()方法,但是不会飞的鸭子一旦多了起来,那么代码就变得非常难以维护和重复。

2..增加Flyable接口,让子类鸭子实现这个接口,然后在类中实现这个fly()方法。但是这样,代码重复太多了。


我们的解决方法是:

将鸭子的飞行行为独立出来,定义一个FlyBehavior接口,然后用FlyWithWings等具体行为类实现此接口


我这里直接上代码:

Duck超类

public abstract class Duck{

//为行为接口类型声明两个引用变量,所有鸭子子类都继承它们
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;

	public  Duck(){}

	public abstract void display();

	public void performFly(){
		flyBehavior.fly();
	}

	public void performQuack(){
		//鸭子对象不亲自处理呱呱叫行为,而是委托给quackBehavior引用的对象
		quackBehavior.quack();
	}

	public void swim(){
		System.out.println("All ducks float, event decoys!");
	}
}

鸭子子类

public class MallardDuck extends Duck{

	public MallardDuck(){
		//quackBehavior是从父类继承来的
		quackBehavior = new Quack();
		flyBehavior = new FlyWithWings();
	}

	publicvoid display(){
		System.out.println("I'm a real Mallard duck");
	}
}

FlyBehavior接口与两个行为实现类FlyWithWings和FlyNoWay

//所有飞行行为类必须实现的接口
public interface FlyBehavior{
	public void fly();
}

//这是飞行行为的实现
public class FlyWithWings implements FlyBehavior{
	public void fly(){
		System.out.println("I'm flying!!");
	}
}

pulic class FlyNoWat implements FlyBehavior{
	public void fly(){
		System.out.println("I can't fly");
	}
}

//所有鸣叫行为必须实现的接口
public interface QuackBehavior{
	public void quack();
}

//这是鸣叫行为的实现
public class Quack implements QuackBehavior{
	public void quack(){
		System.out.println("Quack");
	}
}

public class MuteQuack implements QuackBehavior{
	public void quack(){
		System.out.println("<<Silence");
	}
}

public class Squeak implements QuackBehavior{
	public void quack(){
		System.out.println("Squeak");
	}
}


编译并测试

public class MiniDuckSimulator{
	public static void main(String[] args){
		/*这里使用了向上转型,不清楚的我简单说一下
		因为子类是对父类的一并改进和扩大, 定义一个父类类型的引用指向一个子类的对象既可以使用子类
		强大的功能,也可以抽取父类的共性。父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中
		没有的方法,父类引用是无法调用的。*/
		Duck mallard = new MallardDuck();
		mallard.performQuack();
		mallard.performFly();
	}
}


下面是总结的设计原则:

1.找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起

2.针对接口编程,而不是针对实现编程

3.多用组合,少用继承。比如将鸭子飞行独立出来。


策略模式:

    定义了算法簇,分别封装起来, 让他们之间可以相互替换。此模式让算法的变化独立于使用算法的客户。

    


猜你喜欢

转载自blog.csdn.net/qq_32252957/article/details/80467374