观察者模式和装饰模式
一.验证观察者模式一,实现求职中心的模拟
1.实验内容和源程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| Subject.java public interface Subject{ public void addObserver(Observer o); public void deleteObserver(Observer o); public void notifyObservers(); } Observer.java public interface Observer{ public void hearTelephone(String heardMess); } SeekJobCenter.java import java.util.ArrayList; public class SeekJobCenter implements Subject{ String mess; boolean changed; ArrayList<Observer> personList; SeekJobCenter(){ personList=new ArrayList<Observer>(); mess=""; changed=false; } public void addObserver(Observer o){ if(!(personList.contains(o))) personList.add(o); } public void deleteObserver(Observer o){ if(personList.contains(o)) personList.remove(o); } public void notifyObservers(){ if(changed){ for(int i=0;i<personList.size();i++){ Observer observer=personList.get(i); observer.hearTelephone(mess); } changed=false; } } public void giveNewMess(String str){ if(str.equals(mess)) changed=false; else{ mess=str; changed=true; } } } UniverStudent.java import java.io.*; public class UniverStudent implements Observer{ Subject subject; File myFile; UniverStudent(Subject subject,String fileName){ this.subject=subject; subject.addObserver(this); myFile=new File(fileName); } public void hearTelephone(String heardMess){ try{ RandomAccessFile out=new RandomAccessFile(myFile,"rw"); out.seek(out.length()); byte [] b=heardMess.getBytes(); out.write(b); System.out.print("我是一个大学生,"); System.out.println("我向文件"+myFile.getName()+"写入如下内容:"); System.out.println(heardMess); } catch(IOException exp){ System.out.println(exp.toString()); } } }
|
Haigui.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import java.io.*; import java.util.regex.*; public class HaiGui implements Observer{ Subject subject; File myFile; HaiGui(Subject subject,String fileName){ this.subject=subject; subject.addObserver(this); myFile=new File(fileName); } public void hearTelephone(String heardMess){ try{ boolean boo=heardMess.contains("java程序员")||heardMess.contains("软件"); if(boo){ RandomAccessFile out=new RandomAccessFile(myFile,"rw"); out.seek(out.length()); byte [] b=heardMess.getBytes(); out.write(b); System.out.print("我是一个海归,"); System.out.println("我向文件"+myFile.getName()+"写入如下内容:"); System.out.println(heardMess); } else{ System.out.println("我是海归,这次的信息中没有我需要的信息"); } } catch(IOException exp){ System.out.println(exp.toString()); } } }
|
Application.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Application{ public static void main(String args[]){ SeekJobCenter center=new SeekJobCenter(); UniverStudent zhangLin=new UniverStudent(center,"A.txt"); HaiGui wangHao=new HaiGui(center,"B.txt"); center.giveNewMess("腾辉公司需要10个java程序员。"); center.notifyObservers(); center.giveNewMess("海景公司需要8个动画设计师。"); center.notifyObservers(); center.giveNewMess("仁海公司需要9个电工。"); center.notifyObservers(); center.giveNewMess("仁海公司需要9个电工。"); center.notifyObservers(); } }
|
2.实验执行结果
3.本次收获体会
本问题实现观察者接口Observer的类有两个:一个是UniversityStudent的类,另一个是Haigui。UniversityStudent类的调用方法是会见参数引用的字符串保存到一个文件中。
二.验证装饰模式程序二,实现鸟类飞翔的模拟
1.实验内容和源程序
Bird.java
1 2 3
| public abstract class Bird{ public abstract int fly(); }
|
Sparrow.java
1 2 3 4 5 6
| public class Sparrow extends Bird{ public final int DISTANCE=100; public int fly(){ return DISTANCE; } }
|
Decorator.java
1 2 3 4 5 6 7 8
| public abstract class Decorator extends Bird{ protected Bird bird; public Decorator(){ } public Decorator(Bird bird){ this.bird=bird; } }
|
SparrowDecorator.java
1 2 3 4 5 6 7 8
| public abstract class Decorator extends Bird{ protected Bird bird; public Decorator(){ } public Decorator(Bird bird){ this.bird=bird; } }
|
Application.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Application{ public void needBird(Bird bird){ int flyDistance=bird.fly(); System.out.println("这只鸟能飞行"+flyDistance+"米"); } public static void main(String args[]){ Application client=new Application(); Sparrow sparrow=new Sparrow(); SparrowDecorator sparrowDecorator1= new SparrowDecorator(sparrow); SparrowDecorator sparrowDecorator2= new SparrowDecorator(sparrowDecorator1); client.needBird(sparrowDecorator1); client.needBird(sparrowDecorator2); } }
|
2.实验执行结果
3.本次收获体会
装饰模式中非常重要的一点就是“具体组件”和“装饰”都是“抽象组件”的子类。用户如果需要电泳“被装饰者”源氏的方法就让“抽象组件”声明的对象存放装饰者的作用。
三.设计使用多个装饰者的鸟类飞翔程序
1.实验内容和源程序
Bird.java
1 2 3
| public abstract class Bird{ public abstract int fly(); }``
|
Sparrow.java
1 2 3 4 5 6
| public class Sparrow extends Bird{ public final int DISTANCE=60; public int fly(){ return DISTANCE; } }
|
Decorator.java
1 2 3 4 5 6 7 8
| public abstract class Decorator extends Bird{ protected Bird bird; public Decorator(){ } public Decorator(Bird bird){ this.bird=bird; } }
|
SparrowDecorator.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class SparrowDecorator extends Decorator{ public final int DISTANCE=40; SparrowDecorator(Bird bird){ super(bird); } public int fly(){ int distance=0; distance=bird.fly()+eleFly(); return distance; } private int eleFly(){ return DISTANCE; } }
|
SparrowDecoratorTwo.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class SparrowDecoratorTwo extends Decorator{ public final int DISTANCE=20; SparrowDecoratorTwo(Bird bird){ super(bird); } public int fly(){ int distance=0; distance=bird.fly()+eleFly(); return distance; } public int eleFly(){ return DISTANCE; } }
|
Application.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Application{ public void needBird(Bird bird){ int flyDistance=bird.fly(); System.out.println("这只鸟能飞行"+flyDistance+"米"); } public static void main(String args[]){ Application client=new Application(); Bird bird1=new SparrowDecoratorTwo(new Sparrow()); Bird bird2=new SparrowDecorator(bird1); Bird bird3=new SparrowDecorator(bird2); Bird bird4=new SparrowDecoratorTwo(bird3); client.needBird(bird1); client.needBird(bird2); client.needBird(bird3); client.needBird(bird4); } }
|
2.实验执行结果
3.本次收获体会
由于装饰是抽象组件的一个子类,因此“装饰者”本身也可以作为一个“被装饰者”,这意味着可以使用多个具体装饰类来装饰具体组件的实例。
本文使用 CC BY-NC-SA 3.0 中国大陆 协议许可
具体请参见 知识共享协议
本文链接:https://zyhang8.github.io/2019/11/07/design-exp2/