ooa(面向对象分析 analysis): 要干什么? ood(面向对象设计 design): 怎么做? 面向对象的三大特称:封装,继承,多态。 模拟一下情形: 小孩在睡觉 醒来要求我喂他吃东西 先抽象出有哪些类,在确定每个类有哪些属性(变量而非方法)。 利用要求中有哪些名词来确定(其中的名词可能是类也可能是属性)。 用设计模式,会使复杂度增加,开发成本增加,维护成本降低。 第一种方法(Dad主动监测Child是否醒来,比较耗费资源): class Child implements Runnable{ private boolean wakenUp = false; void wakeUp(){ wakenUp = true; } public boolean isWakenUp() { return wakenUp; } public void setWakenUp(boolean wakenUp) { this.wakenUp = wakenUp; } public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } this.wakeUp(); } } class Dad implements Runnable{ Child c; public Dad(Child c){ this.c = c; } public void run(){ while(!c.isWakenUp()){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } feed(c); } private void feed(Child c2) { System.out.println("feed child!"); } } public class Test { public static void main(String args[]){ Child d = new Child(); new Thread(d).start(); new Thread(new Dad(d)).start(); } } 第二种方法(Dad不主动监测,Child醒来后调用,不具备可扩扩展,没有弹性): class Child implements Runnable{ private boolean wakenUp = false; private Dad d; void wakeUp(){ wakenUp = true; d.feed(this); } public Child(Dad d){ this.d=d; } public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } this.wakeUp(); } } class Dad{ public void feed(Child c2) { System.out.println("feed child!"); } } public class Test { public static void main(String args[]){ Dad d = new Dad(); Child c = new Child(d); new Thread(c).start(); } } 对于Child醒来会有不同的情况(如在哪里醒,什么时候醒,不同时候喂不同的东西),将这些信息告诉Dad。 第三种方法(将小孩醒来的情况封装为一个事件类): class WakenUpEvent{ private long time; private String loc; private Child source; public long getTime() { return time; } public void setTime(long time) { this.time = time; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } public Child getSource() { return source; } public void setSource(Child source) { this.source = source; } public WakenUpEvent(long time, String loc, Child source) { super(); this.time = time; this.loc = loc; this.source = source; } } class Child implements Runnable{ private Dad d; void wakeUp(){ d.ActionToWakenUp(new WakenUpEvent(System.currentTimeMillis(),"bed",this)); } public Child(Dad d){ this.d=d; } public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } this.wakeUp(); } } class Dad{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent) { System.out.println("feed child!"); } } public class Test { public static void main(String args[]){ Dad d = new Dad(); Child c = new Child(d); new Thread(c).start(); } } 第四种方法(醒来之后,爷爷、奶奶、叔叔等也要做出反应): import java.util.ArrayList; import java.util.List; class WakenUpEvent{ private long time; private String loc; private Child source; public long getTime() { return time; } public void setTime(long time) { this.time = time; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } public Child getSource() { return source; } public void setSource(Child source) { this.source = source; } public WakenUpEvent(long time, String loc, Child source) { super(); this.time = time; this.loc = loc; this.source = source; } } class Child implements Runnable{ private List<WakenUpListener> wakenUpListeners=new ArrayList<WakenUpListener>(); public void addWakenUpListener(WakenUpListener l){ wakenUpListeners.add(l); } void wakeUp(){ for(int i=0;i<wakenUpListeners.size();i++){ WakenUpListener l = wakenUpListeners.get(i); l.ActionToWakenUp(new WakenUpEvent(System.currentTimeMillis(),"bed",this)); } } public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } this.wakeUp(); } } class Dad implements WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent) { System.out.println("feed child!"); } } class GrandFather implements WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent) { System.out.println("hug child!"); } } interface WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent); } public class Test { public static void main(String args[]){ Dad d = new Dad(); Child c = new Child(); GrandFather gf = new GrandFather(); c.addWakenUpListener(d); c.addWakenUpListener(gf); new Thread(c).start(); } } 除了WakenUpEvent,还可以有哭事件等等,类似的定义事件接口。 项目中的class编译好之后会放到bin目录中,而bin默认设置在本项目中的classpath之下。 String类的方法为重点。 第四种方法(利用配置文件设置,使我们不用改main方法,只用增加类和改配置文件即可增加新的监听者): import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; class WakenUpEvent{ private long time; private String loc; private Child source; public long getTime() { return time; } public void setTime(long time) { this.time = time; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } public Child getSource() { return source; } public void setSource(Child source) { this.source = source; } public WakenUpEvent(long time, String loc, Child source) { super(); this.time = time; this.loc = loc; this.source = source; } } class Child implements Runnable{ private List<WakenUpListener> wakenUpListeners=new ArrayList<WakenUpListener>(); public void addWakenUpListener(WakenUpListener l){ wakenUpListeners.add(l); } void wakeUp(){ for(int i=0;i<wakenUpListeners.size();i++){ WakenUpListener l = wakenUpListeners.get(i); l.ActionToWakenUp(new WakenUpEvent(System.currentTimeMillis(),"bed",this)); } } public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } this.wakeUp(); } } class Dad implements WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent) { System.out.println("feed child!"); } } class GrandFather implements WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent) { System.out.println("hug child!"); } } interface WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent); } public class Test { public static void main(String args[]){ Child c = new Child(); Properties props = new Properties(); try { props.load(Test.class.getClassLoader().getResourceAsStream("observer.properties")); } catch (IOException e) { e.printStackTrace(); } String[] observers = props.getProperty("observers").split(","); for(String s : observers){ try { c.addWakenUpListener((WakenUpListener)Class.forName(s).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } new Thread(c).start(); } } ----observer.properties---- //配置文件 observers=Dad,GrandFather 第五种方法(单例模式): import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; class WakenUpEvent{ private long time; private String loc; private Child source; public long getTime() { return time; } public void setTime(long time) { this.time = time; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } public Child getSource() { return source; } public void setSource(Child source) { this.source = source; } public WakenUpEvent(long time, String loc, Child source) { super(); this.time = time; this.loc = loc; this.source = source; } } class Child implements Runnable{ private List<WakenUpListener> wakenUpListeners=new ArrayList<WakenUpListener>(); public void addWakenUpListener(WakenUpListener l){ wakenUpListeners.add(l); } void wakeUp(){ for(int i=0;i<wakenUpListeners.size();i++){ WakenUpListener l = wakenUpListeners.get(i); l.ActionToWakenUp(new WakenUpEvent(System.currentTimeMillis(),"bed",this)); } } public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } this.wakeUp(); } } class Dad implements WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent) { System.out.println("feed child!"); } } class GrandFather implements WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent) { System.out.println("hug child!"); } } interface WakenUpListener{ public void ActionToWakenUp(WakenUpEvent wakenUpEvent); } class PropertyMgr{ private static Properties props = new Properties(); static { try { props.load(Test.class.getClassLoader().getResourceAsStream("observer.properties")); } catch (IOException e) { e.printStackTrace(); } } public static String getProperty(String key){ return props.getProperty(key); } } public class Test { public static void main(String args[]){ Child c = new Child(); String[] observers = PropertyMgr.getProperty("observers").split(","); for(String s : observers){ try { c.addWakenUpListener((WakenUpListener)Class.forName(s).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } new Thread(c).start(); } }