首页 >> 大全

java 设计模式之2策略模式

2023-10-03 大全 42 作者:考证青年

学习设计原则之前先了解java OO基础:

几个重要面向对象设计原则:

一. 一步步开始设计类图

针对鸭子 我们设计类结构及之间的关系。

按照一般的想法,我们会设计一个超类Duck,方法有quack(),swim()等,其他子类鸭子统统继承这个超类Duck,这样子类就不用重新写相关方法,增加了代码复用性。类图如下:

模式策略方法_设计模式之策略模式_

此时如果想增加一个行为fly,把他添加到Duck超类,那么子类同样都可以继承。但是如果有一只玩具鸭他不会飞,那么在超累Duck中添加fly方法,就会有问题了,玩具鸭不该具有的飞行fly行为,却被玩具鸭从Duck类继承了!

你又想到,可以使用继承然后覆盖重写超类的方法,玩具鸭重写fly方法,变成不会飞,这样确实可行!但如果有一只鸭子不会飞,但又会瓜瓜叫,又有一只鸭子会飞但不会瓜瓜叫…如果有类似的鸭子n只,岂不是每个类都需要重写覆盖一些方法么?可见使用继承Duck,这种方式有一些死板,超类Duck的行为,继承的子类不一定都具有Duck的行为,而且代码在子类中都会有重复,且子类鸭子的行为不能轻易改变。

我们说到面向接口编程,少用继承,把变化的部分拿出来封装。那么我们把可能会发生变化的行为 Fly行为和Quak叫的行为都从Duck超类拿出来,形成两个接口。使各种各样的fly的行为,如,,或者叫的行为,如Quack方式叫,方式叫,去实现这两个接口。

设计模式之策略模式_模式策略方法_

这样一来,飞行的行为和叫的行为被单独拿出来了,已经与Duck类无关,弹性增加。

上方已经把和从Duck超类中剥离,那么怎样让Duck类使用到这两个行为呢?采用委托代理的方式,在Duck类中添加这两个接口,通过这两个接口执行具体的fly行为或quack行为。Duck类如图:

_模式策略方法_设计模式之策略模式

子类鸭子如何设定和的实例呢?

通过构造的方式,来实例化具体的行为(这种方式有些死板,因为具体的行为是静态构造的,稍后我们通过其他方法使之能动态改变)

构造方式如下:

/*
这是一直会吱吱叫和会飞行的鸭子
*/
public class OneFlyDuck2 extends Duck {public OneFlyDuck2() {quackBehavior = new QuackWithSqueak(); //flyBehavior = new FlyWithWings(); // 用翅膀飞行}}

二.代码编写: 2.1第一次编码实现:

Duck超类:

鸭子都有的固定的属性或者行为
*/
public class Duck {FlyBehavior flyBehavior;   //声明两个行为QuackBehavior quackBehavior;//都会游泳public void swim(){System.out.println("I can swim");};// 游泳public void performFlyBehavior(){flyBehavior.fly();  //使用flyBeahvior接口代理执行飞的具体行为}public void performQuackBehavior(){quackBehavior.quack();//使用QuackBehavior接口代理执行叫的具体行为}

:

/*
各种飞的接口 
*/
public interface FlyBehavior{void fly();//各种飞}

:

/*
叫的接口
*/
public interface QuackBehavior {void quack();//叫
}

实现接口:

public class FlyWithWings implements FlyBehavior {@Overridepublic void fly(){System.out.println("I fly with Wings!");}
}

实现接口:


public class FlyWithNoWay implements FlyBehavior {@Overridepublic void fly(){System.out.println("I fly with noWay!");}
}

实现接口:

/*
吱吱叫 
*/
public class Squeak implements QuackBehavior{@Overridepublic void quack(){System.out.println("I  can Sequack!");  }    
}

Quack叫实现接口:

/*
瓜瓜叫
*/
public class Quack  implements QuackBehavior {public void quack(){System.out.println("I can Quack!");}
}

一个子类鸭子:

/*
这是一直会吱吱叫和会飞行的鸭子
*/
public class OneFlyDuck2 extends Duck {public OneFlyDuck2() {quackBehavior = new Squeak(); //flyBehavior = new FlyWithWings(); // 用翅膀飞行}
}

测试类:

public static void main(String[] args) {Duck oneflyDuck2=new OneFlyDuck2();FlyBehavior flyBehavior=new FlyWithWings(); //翅膀飞行QuackBehavior quackBehavior1=new Squeak(); //吱吱方式叫oneflyDuck2.performFlyBehavior();;  //这种事oneFlyDuck 构造方式创建的oneflyDuck2.performQuackBehavior();
}

结果:

2.2 第二次编码改进

上方是通过子类构造器方式实例化鸭子具有的行为,这样比较僵硬,有一种方式可以动态地set设定鸭子的行为,方式如下:**

在Duck类中新增set方法,设定具体的飞的行为or叫的行为,然后子类中不需要构造了。

_模式策略方法_设计模式之策略模式

新Duck类:

/*
鸭子都有的固定的属性或者行为
*/
public class Duck {FlyBehavior flyBehavior;   //声明两个行为QuackBehavior quackBehavior;//都会游泳public void swim(){System.out.println("I can swim");};// 游泳public void performFlyBehavior(){flyBehavior.fly();}public void performQuackBehavior(){quackBehavior.quack();}//新增的方法public void setFlyBehavior(FlyBehavior flyBehavior1){this.flyBehavior=flyBehavior1;}public void setQuackBehavior(QuackBehavior quackBehavior1){this.quackBehavior=quackBehavior1;}
}

新子类:

/*
这是某一种鸭子
*/
public class OneFlyDuck extends Duck{
}

测试类:

 public static void main(String[] args) {Duck oneflyDuck=new OneFlyDuck();FlyBehavior flyBehavior=new FlyWithWings(); //翅膀飞行  父类接口指向子类引用QuackBehavior quackBehavior1=new Squeak(); //吱吱方式叫  父类接口指向子类引用oneflyDuck.setFlyBehavior(flyBehavior);//传递会飞的行为oneflyDuck.setQuackBehavior(quackBehavior1); //传递会叫的行为。oneflyDuck.performFlyBehavior();//执行飞的行为oneflyDuck.performQuackBehavior();//执行叫的行为}

结果:

2.3额外补充

如果新增一只鸭子,他是用火箭实现飞行的,那么只需要新建一个火箭飞行类实现接口,而不需要修改原有代码.

/*
新增加的飞行方式
*/
public class RocketFly implements FlyBehavior{@Overridepublic void fly(){System.out.println("I can fly with Rocket!!");}    
}

测试:

public static void main(String[] args) {Duck duckRocket=new OneRocketDuck();FlyBehavior flyBehavior2=new RocketFly(); //实例化 使用火箭飞的行为duckRocket.setFlyBehavior(flyBehavior2);//设定飞的行为 是通过火箭方式duckRocket.performFlyBehavior();//执行fly}

代码的执行过程:

是指向子类的父类引用,因为多态特性,因此可以调用在Duck类中的方法。

是指向子类的父接口引用,将作为参数传入方法,就是实例化了Duck类中的。

最后使用调用方法,就是执行了.fly(),因为多态,且已经第二步实例化了,因此调用的就是中的fly方法。

结果:

三.最终类设计图

模式策略方法_设计模式之策略模式_

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了