设计模式
1、设计模式是人们在面对同类型软件工程设计问题所总结出的一些有用的经验。模式不是代码,而是某类问题的通用设计解决方案。
2、4人组Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides总结写了《设计模式》
3、设计模式的本质目的是使软件工程在维护性、扩展性、变化性、复杂度方面成O(N)。
一、策略模式
例子:模拟鸭子项目:
package strategy.extraction;
public abstract class Duck {
public Duck() {
}
public void Quack() {
System.out.println("~~~~~gaga~~~~");
}
public abstract void display();
public void Swim() {
System.out.println("~~~~~swin~~~~");
}
}
package strategy.extraction;
public class GreenHeadDuck extends Duck {
@Override
public void display() {
System.out.println("**GreenHeadDuck**");
}
}
package strategy.extraction;
public class RedHeadDuck extends Duck {
@Override
public void display() {
System.out.println("**RedDuck**");
}
}
package strategy.extraction;
public class Test {
public static void main(String[] args) {
GreenHeadDuck mGreenHeadDuck = new GreenHeadDuck();
mGreenHeadDuck.display();
mGreenHeadDuck.Quack();
mGreenHeadDuck.Swim();
RedHeadDuck redHeadDuck = new RedHeadDuck();
redHeadDuck.display();
redHeadDuck.Quack();
redHeadDuck.Swim();
}
}
略模策略模式原理式原理略模式原理
应对新的需求,看看这个设计的可拓展性。
1、)添加会飞的鸭子
2、 OO思想里的继承方式解决方案是:在Duck类中添加Fly() 方法。
public abstract class Duck {
public Duck() {
}
public void Quack() {
System.out.println("~~~~~gaga~~~~");
}
public abstract void display();
public void Swim() {
System.out.println("~~~~~swin~~~~");
}
//添加Fly()方法
public void Fly() {
System.out.println("~~~~~fly~~~~");
}
}
那么问题来了,这个Fly让所有的子类都会飞了,这是不科学的,比如说煮熟的鸭子。
继承的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分,影响会有溢出效应。
继续尝试用OO原理来解决,覆盖,也就是说在子类中覆盖父类的Fly()方法。
package strategy.extraction;
public class GreenHeadDuck extends Duck {
@Override
public void display() {
System.out.println("**GreenHeadDuck**");
}
@Override
public void Fly() {
System.out.println("--I can't fly--");
}
}
但是这样还是存在问题,那就是要让每一个子类都要重写Fly()方法,也就是说:
超类挖的坑,每个子类都要来填,增加工作量,复杂度O(N^2),不是好的设计模式。
策略模式的诞生:
重新设计的鸭子项目:
策略模式:分别封装行为接口,实现算法族,超类里放欣慰接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,
封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者。
package strategy.produce;
public interface FlyBehavior {
void fly();
}
package strategy.produce;
public class GoodFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println(" good fly");
}
}
package strategy.produce;
public class BadFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("bad Fly");
}
}
package strategy.produce;
public interface QuackBehavior {
void quack();
}
package strategy.produce;
public class GaGaQuackBehavior implements QuackBehavior{
@Override
public void quack() {
System.out.println("gaga");
}
}
package strategy.produce;
public class KuaiKuaiQuackBehavior implements QuackBehavior{
@Override
public void quack() {
System.out.println("kuai kuai");
}
}
package strategy.produce;
public abstract class Duck {
FlyBehavior FlyBehavior;
QuackBehavior QuackBehavior;
public Duck() {
}
public void Quack() {
QuackBehavior.quack();
}
public abstract void display();
public void Swim() {
System.out.println("~~~~~swin~~~~");
}
public void Fly() {
FlyBehavior.fly();
}
public FlyBehavior getFlyBehavior() {
return FlyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
FlyBehavior = flyBehavior;
}
public QuackBehavior getQuackBehavior() {
return QuackBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
QuackBehavior = quackBehavior;
}
}
package strategy.produce;
public class GreenHeadDuck extends Duck {
public GreenHeadDuck() {
FlyBehavior = new BadFlyBehavior();
QuackBehavior = new KuaiKuaiQuackBehavior();
}
@Override
public void display() {
System.out.println("**GreenHeadDuck Display**");
}
}
package strategy.produce;
public class RedHeadDuck extends Duck {
public RedHeadDuck() {
FlyBehavior = new GoodFlyBehavior();
QuackBehavior = new GaGaQuackBehavior();
}
@Override
public void display() {
System.out.println("**RedDuck**");
}
}
package strategy.produce;
public class Test {
public static void main(String[] args) {
Duck mGreenHeadDuck = new GreenHeadDuck();
mGreenHeadDuck.display();
mGreenHeadDuck.Quack();
mGreenHeadDuck.Swim();
mGreenHeadDuck.Fly();
Duck redHeadDuck = new RedHeadDuck();
redHeadDuck.display();
redHeadDuck.Quack();
redHeadDuck.Swim();
redHeadDuck.Fly();
redHeadDuck.setFlyBehavior(new BadFlyBehavior());
redHeadDuck.Fly();
}
}
注意点:
1、分析项目中变化部分与不变化部分。
2、多用组合少用继承;用行为组合,而不是行为的继承,更有弹性。