1、策略模式(Strategy Pattern)
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数。
AbstractCalculator是辅助类,提供辅助方法,接下来,依次实现下每个类:
首先统一接口:
- public interface ICalculator {
- public int calculate(String exp);
- }
辅助类:
- public abstract class AbstractCalculator {
- public int[] split(String exp,String opt){
- String array[] = exp.split(opt);
- int arrayInt[] = new int[2];
- arrayInt[0] = Integer.parseInt(array[0]);
- arrayInt[1] = Integer.parseInt(array[1]);
- return arrayInt;
- }
- }
三个实现类:
- public class Plus extends AbstractCalculator implements ICalculator {
- @Override
- public int calculate(String exp) {
- int arrayInt[] = split(exp,"\\+");
- return arrayInt[0]+arrayInt[1];
- }
- }
- public class Minus extends AbstractCalculator implements ICalculator {
- @Override
- public int calculate(String exp) {
- int arrayInt[] = split(exp,"-");
- return arrayInt[0]-arrayInt[1];
- }
- }
- public class Multiply extends AbstractCalculator implements ICalculator {
- @Override
- public int calculate(String exp) {
- int arrayInt[] = split(exp,"\\*");
- return arrayInt[0]*arrayInt[1];
- }
- }
简单的测试类:
- public class StrategyTest {
- public static void main(String[] args) {
- String exp = "2+8";
- ICalculator cal = new Plus();
- int result = cal.calculate(exp);
- System.out.println(result);
- }
- }
输出:10
策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。
再写一个例子,模拟鸭子的问题,鸭子有飞,叫,游泳行为,如果在父类中都规定写好飞,叫,游泳行为,再用子类继承父类,但是鸭子飞和叫的行为有时候会不一样,有的呱呱叫,有的吱吱叫,还有的鸭子根本不会飞,缺有了飞的行为。那么在父类中抽象飞,叫的行为,让子类各自去实现呢,如果不会飞 就覆盖父类中飞的方法变成什么都不做,但是以后每次变更鸭子行为,新增鸭子时都要考虑鸭子飞,叫的行为,这时候我们发现飞和叫的行为是会变的,根据设计原则找出应用中可能需要变化的地方,把它们独立出来,不要和那些不变的混在一起,也就是说把变化的封装起来。我们把鸭子变的部分飞和叫的行为,变成鸭子对象的一种变量,而不把它当做一种行为方法,在创建对象时动态的改变它的这些行为属性,代码如下
鸭子的父类
package com.remote3c.main;
import com.remote3c.inter.FlyBehavior;
import com.remote3c.inter.QuckBehavior;
/**
*
* @author zhangyoushuai
*/
public abstract class Duck {
private FlyBehavior flyBehavior;//把鸭子飞的行为当做成员变量
private QuckBehavior quckBehavior;
public void swim(){
System.out.println("鸭子游泳都一样……");
};
public void performFly(){
quckBehavior.fly();
};
public void performQuack(){
flyBehavior.quck();
};
public abstract void display();
public FlyBehavior getFlyBehavior() {
return flyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public QuckBehavior getQuckBehavior() {
return quckBehavior;
}
public void setQuckBehavior(QuckBehavior quckBehavior) {
this.quckBehavior = quckBehavior;
}
}
飞和叫两种行为的接口
package com.remote3c.inter;
public interface FlyBehavior {
void fly();
}
package com.remote3c.inter;
public interface QuckBehavior {
void quck();
}
然后是实现飞和叫行为的具体的类
package com.remote3c.inter.impl;
import com.remote3c.inter.FlyBehavior;
public class FlyWithPlane implements FlyBehavior {
public void fly() {
System.out.println("开着飞机 飞");
}
}
package com.remote3c.inter.impl;
import com.remote3c.inter.FlyBehavior;
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println("有翅膀 忽闪忽闪的飞");
}
}
package com.remote3c.inter.impl;
import com.remote3c.inter.QuckBehavior;
public class GuaGuaQuck implements QuckBehavior {
public void quck() {
System.out.println("呱呱叫…………");
}
}
package com.remote3c.inter.impl;
import com.remote3c.inter.QuckBehavior;
public class ZhiZhiQuck implements QuckBehavior{
public void quck() {
System.out.println("吱吱叫…………");
}
}
接着就是实现父类鸭子的具体鸭子啦
package com.remote3c.main;
public class MallardDuck extends Duck {
@Override
public void display() {
System.out.println("绿头鸭 绿头鸭 绿头鸭");
};
}
package com.remote3c.main;
public class RedheadDuck extends Duck {
@Override
public void display() {
System.out.println("红头鸭 红头鸭 红头鸭 ");
}
}
最后测试类
package com.remote3c.main;
import com.remote3c.inter.FlyBehavior;
import com.remote3c.inter.QuckBehavior;
import com.remote3c.inter.impl.FlyWithPlane;
import com.remote3c.inter.impl.FlyWithWings;
import com.remote3c.inter.impl.GuaGuaQuck;
import com.remote3c.inter.impl.ZhiZhiQuck;
public class Test {
/**
* @author zhangyoushuai
* @date 2016-9-2
* @version 1.0.0
* @param args
*
*/
public static void main(String[] args) {
MallardDuck md=new MallardDuck();
//在这里动态的改变鸭子的行为
//这样的设计,可以让飞行和叫的动作被其他对象复用
//而且我们可以新增一些飞和叫的的行为,并且不影响其他使用飞行行为的鸭子
FlyBehavior fww=new FlyWithPlane();//开着飞机飞。父类引用指向子类对象
md.setFlyBehavior(fww);
QuckBehavior ggq=new GuaGuaQuck();
md.setQuckBehavior(ggq);
md.display();//鸭子名称
md.performQuack();//尽情的叫吧
md.performFly();//飞吧……………………
}
}
测试结果
绿头鸭 绿头鸭 绿头鸭
开着飞机 飞
呱呱叫…………
2、观察者模式(Observer Pattern)
观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。
就是一个对象改变时,其他一些相关联的对象也要随之改变,就可以考虑这种模式
代码特点,观察者实现统一接口和方法,被观察者提供可以盛放观察者的容器,并且提供可以新增和删除观察者的方法,最重要是提供遍历观察者,利用多态调用观察者统一方法的方法。
我们看实现代码:
一个Observer接口:
- public interface Observer {
- public void update();
- }
两个实现类:
- public class Observer1 implements Observer {
- @Override
- public void update() {
- System.out.println("observer1 has received!");
- }
- }
- public class Observer2 implements Observer {
- @Override
- public void update() {
- System.out.println("observer2 has received!");
- }
- }
Subject接口及实现类:
- public interface Subject {
- /*增加观察者*/
- public void add(Observer observer);
- /*删除观察者*/
- public void del(Observer observer);
- /*通知所有的观察者*/
- public void notifyObservers();
- /*自身的操作*/
- public void operation();
- }
- public abstract class AbstractSubject implements Subject {
- private Vector<Observer> vector = new Vector<Observer>();
- @Override
- public void add(Observer observer) {
- vector.add(observer);
- }
- @Override
- public void del(Observer observer) {
- vector.remove(observer);
- }
- @Override
- public void notifyObservers() {
- Enumeration<Observer> enumo = vector.elements();
- while(enumo.hasMoreElements()){
- enumo.nextElement().update();
- }
- }
- }
- public class MySubject extends AbstractSubject {
- @Override
- public void operation() {
- System.out.println("update self!");
- notifyObservers();
- }
- }
测试类:
- public class ObserverTest {
- public static void main(String[] args) {
- Subject sub = new MySubject();
- sub.add(new Observer1());
- sub.add(new Observer2());
- sub.operation();
- }
- }
我解释下这些类的作用:MySubject类就是我们的主对象,Observer1和Observer2是依赖于MySubject的对象,当MySubject变化时,Observer1和Observer2必然变化。AbstractSubject类中定义着需要监控的对象列表,可以对其进行修改:增加或删除被监控对象,且当MySubject变化时,负责通知在列表内存在的对象。
输出:
update self!
observer1 has received!
observer2 has received!
还有JDK本身也提供了,观察者要实现的接口Observer,可被观察者所实现的超类Observable,通过他们也能实现观察者模式