什么是设计模式
设计模式是某类问题的通用设计解决方案
怎么学习设计模式
在以往的工程中寻找能否找到何处可以使用它们
在以后的工程中是否可以使用到设计模式
设计模式的好处
当有新的需求后你对代码的维护性、开发量、程序的可扩展性都大大的降低
策略模式
开发中继承的问题:对类的改动,尤其对超类的改动,会影响其他部分,影响会有溢出效应
比如:有一个鸭子的超类(实现了叫和游泳的具体功能还有个颜色的抽象方法),继承他的有白头鸭、红头鸭、绿头鸭等等10中鸭子
当你有新的需求,需要添加一个飞的需求,
那么你可以选择在超类中添加一个具体实现飞的功能的方法,但是并不是所有的鸭子都是会飞的,
那么你就要对继承的鸭子进行覆写他飞的方法,这样导致代码了大大增加
或者你可以实现一个飞的接口然后让各个子类去实现,但是有很多的代码是一样的,会飞的代码和不会飞的代码,这样代码的复用性就降低了
解决办法:(分析项目的变化和不变化的部分,提取变化的部分,抽象成接口+实现)
我们可以将变化的行为提取出来封装成接口,然后超类中放接口,在子类中实现接口
例如:将“飞”和“叫”封装成接口,不同的鸭子有不同的飞和叫声 然后创建行为类实现这个接口
然后设置鸭子这个超类,里面放接口(飞和叫声)并提供一个调用的方法(调用飞和叫 接口.飞 接口.叫)
然后在子类中具体实现它是如何飞和如何叫(实例化一个行为类給它)
专业术语:分别封装行为接口,实现算法族,超类中放行为接口对象,在子类中具体设置行为对象
原则:分离变化部分,封装接口,基于接口编程各种功能
代码示例:
1.创建一个飞的接口
public interface FlyInterface {
public void Fly();
}
2.实现它的行为类(会飞和不会飞)
public class CanFly implements FlyInterface{
@Override
public void Fly() {
System.out.println("我是会飞的鸭子");
}
}
public class CannotFly implements FlyInterface{
@Override
public void Fly() {
System.out.println("我是不会飞的鸭子");
}
}
public class Duck {
public Duck(){
}
FlyInterface mFlyInterface;
public void duckFly(){
mFlyInterface.Fly();
}
//动态的改变鸭子的飞
public void changeFly(FlyInterface mFlyInterface){
this.mFlyInterface = mFlyInterface;
}
}
public class CanFlyDuck extends Duck{
public CanFlyDuck(){
mFlyInterface = new CanFly();
}
}
5.在main主函数中调用
public class Main {
public static void main(String[] args) {
Duck duck = new CanFlyDuck();
duck.duckFly();
duck.changeFly(new CannotFly()); //动态的改变它的状态(不会飞)
duck.duckFly();
}
}
输出
我是会飞的鸭子
我是不会飞的鸭子
这样一个策略模式就实现了,当又有新的需求,设计暴力飞的鸭子,那么我们只需要,设计一个行为类实现飞的接口,然后在主函数中实例这个类就能实现了
public class violentFly implements FlyInterface{
@Override
public void Fly() {
System.out.println("我是暴力飞的鸭子");
}
}
public class Main {
public static void main(String[] args) {
Duck duck = new CanFlyDuck();
duck.duckFly();
duck.changeFly(new CannotFly());
duck.duckFly();
duck.changeFly(new violentFly());
duck.duckFly();
}
}
输出
我是会飞的鸭子
我是不会飞的鸭子
我是暴力飞的鸭子
总结
1.分析项目中变化部分和不变化部分
2.多用组合少用继承 用行为类的组合而不是行为的继承