3.09k likes | 3.3k Views
Java. Java. 设计模式. 设计模式. 封面. Java 设计模式. 2014/11/17. 1. Java. Java. 设计模式. 设计模式. 第一章 设计模式简介. 每一个设计模式描述一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次一次地使用该方案而不必做重复劳动。. 1.1 什么是设计模式. 2014/11/17. 2. Java. Java. 设计模式. 设计模式. 软件领域的设计模式 起源于建筑学 。
E N D
Java Java 设计模式 设计模式 封面 Java设计模式 2014/11/17 1
Java Java 设计模式 设计模式 第一章 设计模式简介 每一个设计模式描述一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次一次地使用该方案而不必做重复劳动。 1.1 什么是设计模式 2014/11/17 2
Java Java 设计模式 设计模式 软件领域的设计模式起源于建筑学。 1977年,建筑大师Alexander出版了《A Pattern Language:Towns, Building, Construction》一书。受Alexander著作的影响 ,Kent Beck和Ward Cunningham在1987年举行的一次面向对象的会议上发表了论文:《在面向对象编程中使用模式》。 1.2 设计模式的起源 2014/11/17 3
Java Java 设计模式 设计模式 目前,被公认在设计模式领域最具影响力的著作是Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides在1994年合作出版的著作:《Design Patterns:Elements of Reusable Object-Oriented Software》(中译本《设计模式:可复用的面向对象软件的基本原理》 或《设计模式》),该书被广大喜爱者昵称为GOF(Gang of Four)之书,被认为是学习设计模式的必读著作,GOF之书已经被公认为是设计模式领域的奠基之作。 1.3 GOF之著作 2014/11/17 4
Java Java 设计模式 设计模式 学习设计模式不仅可以使我们使用好这些成功的模式,更重要的是可以使我们更加深刻地理解面向对象的设计思想,非常有利于我们更好地使用面向对象语言解决设计中的问题。 1.4 学习设计模式的重要性 2014/11/17 5
Java Java 设计模式 设计模式 1.正确使用 2.避免教条 3.模式挖掘 1.5 合理使用模式 2014/11/17 6
Java Java 设计模式 设计模式 第二章 面向对象的几个基本原则 设计一个类时,不让该类面向具体的类,而是面向抽象类或接口 。 2.1 面向抽象原则 2014/11/17 7
Java Java 设计模式 设计模式 第二章 面向对象的几个基本原则 public class Circle{ double r;Circle(double r){this.r=r;} public double getArea(){ return 3.14*r*r;}} 定义底面为三角形的柱体? public class Pillar{ Circle bottom; double height; Pillar(Circle bottom,double height){ this.bottom=bottom;this.height=height;}} 2014/11/17 8
Java Java 设计模式 设计模式 第二章 面向对象的几个基本原则 public abstract class Geometry{ public abstract double getArea(); } public class Pillar{ Geometry bottom; double height; Pillar(Circle bottom,double height){ this.bottom=bottom;this.height=height;}} 2014/11/17 9
Java Java 设计模式 设计模式 设计应当对扩展开放,对修改关闭。 如果您的设计遵守了“开-闭原则”,那么这个设计一定是易维护的,因为在设计中增加新的模块时,不必去修改设计中的核心模块。 2.2 开-闭原则 2014/11/17 10
Java Java 设计模式 设计模式 如果类中的方法是一组相关的行为,则称该类是高内聚的,反之称为低内聚的。 所谓低耦合就是尽量不要让一个类含有太多的其它类的实例的引用,以避免修改系统的其中一部分会影响到其它部分。 2.3 高内聚-低耦合原则 2014/11/17 11
Java Java 设计模式 设计模式 第四章 命令模式 命令模式(别名:动作,事务) 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。 Command Pattern(Another Name: Action, Transaction) Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. 2014/11/17 12
Java Java 设计模式 设计模式 在许多设计中,经常涉及到一个对象请求另一个对象调用其方法到达某种目的。如果请求者不希望或无法直接和被请求者打交道,即不希望或无法含有被请求者的引用,那么就可以使用命令模式。 一 、 概述 2014/11/17 13
实例 在军队作战中,指挥官请求三连偷袭敌人,但是指挥官不希望或无法直接与三连取得联系,那么可以将该请求:“三连偷袭敌人”形成一个“作战命令”。只要能让该作战命令被执行,就会实现三连偷袭敌人的目的。
Java Java 设计模式 设计模式 • 模式的结构中包括四种角色: • 接收者(Receiver) • 命令(Command)接口 • 具体命令(ConcreteCommand) • 请求者(Invoker) 二、命令模式的结构与使用 2014/11/17 15
Java Java 设计模式 设计模式 模式的UML类图 2014/11/17 16
Java Java 设计模式 设计模式 模式的结构的描述与使用 1.接收者(Receiver) : CompanyArmy.java public class CompanyArmy{ public void sneakAttack(){ System.out.println("我们知道如何偷袭敌人,保证完成任务"); } } 2014/11/17 17
Java Java 设计模式 设计模式 模式的结构的描述与使用 2.命令(Command)接口 : Command.java public interface Command { public abstract void execute(); } 2014/11/17 18
Java Java 设计模式 设计模式 模式的结构的描述与使用 3.具体命令(ConcreteCommand) ConcreteCommand.java public class ConcreteCommand implements Command{ CompanyArmy army; //含有接收者的引用 ConcreteCommand(CompanyArmy army){ this.army=army; } public void execute(){ //封装着指挥官的请求 army.sneakAttack(); //偷袭敌人 } } 2014/11/17 19
Java Java 设计模式 设计模式 模式的结构的描述与使用 4.请求者(Invoker) ArmySuperior.java public class ArmySuperior{ Command command; //用来存放具体命令的引用 public void setCommand(Command command){ this.command=command; } public void startExecuteCommand(){ //让具体命令执行execute()方法 command.execute(); } } 2014/11/17 20
Java Java 设计模式 设计模式 模式的结构的描述与使用 5.应用 Application.java public class Application{ public static void main(String args[]){ CompanyArmy 三连=new CompanyArmy(); Command command=new ConcreteCommand(三连); ArmySuperior 指挥官=new ArmySuperior(); 指挥官.setCommand(command); 指挥官.startExecuteCommand(); } } 2014/11/17 21
Java Java 设计模式 设计模式 • 在命令模式中,请求者(Invoker)不直接与接收者(Receiver)交互,即请求者(Invoker)不包含接收者(Receiver)的引用,因此彻底消除了彼此之间的耦合。 • 命令模式满足“开-闭原则”。如果增加新的具体命令和该命令的接受者,不必修改调用者的代码,调用者就可以使用新的命令对象;反之,如果增加新的调用者,不必修改现有的具体命令和接受者,新增加的调用者就可以使用已有的具体命令。 三、命令模式的优点 2014/11/17 22
四、应用举例 • 模拟带控制开关的小电器。该电器上有四个开关,两个一组,其中一组负责打开、关闭小电器上的照明灯,另一组负责打开、关闭小电器上的摄像头。
Java Java 设计模式 设计模式 第五章 观察者模式 观察者模式(别名:依赖,发布-订阅) 定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。 Observer Pattern(Another Name: Dependents, Publish-Subscribe) Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.. 2014/11/17 24
Java Java 设计模式 设计模式 在许多设计中,经常涉及到多个对象都对一个特殊对象中的数据变化感兴趣,而且这多个对象都希望跟踪那个特殊对象中的数据变化。 一 、 概述 2014/11/17 25
实例 • 某些寻找工作的人对“求职中心”的职业需求信息的变化非常关心,很想跟踪“求职中心”中职业需求信息的变化。“求职者”可以让“求职中心”把自己登记下来,这样求职中心就会及时通知她最新的职业信息需求。
Java Java 设计模式 设计模式 • 观察者模式的结构中包括四种角色: • 主题(Subject) • 观察者(Observer) • 具体主题(ConcreteSubject) • 具体观察者(ConcreteObserver) 二、 模式的结构与使用 2014/11/17 27
Java Java 设计模式 设计模式 模式的UML类图 2014/11/17 28
Java Java 设计模式 设计模式 模式的结构的描述与使用 1.主题 : Subject.java public interface Subject{ public void addObserver(Observer o); public void deleteObserver(Observer o); public void notifyObservers(); } 2014/11/17 29
Java Java 设计模式 设计模式 模式的结构的描述与使用 2.观察者 : Obsever.java public interface Observer{ public void hearTelephone(String heardMess); } 2014/11/17 30
Java Java 设计模式 设计模式 模式的结构的描述与使用 3.具体主题 SeekJobCenter.java_1 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); } 2014/11/17 31
Java Java 设计模式 设计模式 模式的结构的描述与使用 3.具体主题 SeekJobCenter.java_2 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; } } } 2014/11/17 32
Java Java 设计模式 设计模式 模式的结构的描述与使用 4.具体观察者_1 UniversityStudent.java import java.io.*; public class UniverStudent implements Observer{ Subject subject; File myFile; UniverStudent(Subject subject,String fileName){ this.subject=subject; subject.addObserver(this); //使当前实例成为subject所引用的具体主题的观察者 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()); } } } 2014/11/17 33
Java Java 设计模式 设计模式 模式的结构的描述与使用 4.具体观察者_2 HaiGui.java 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); //使当前实例成为subject所引用的具体主题的观察者 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()); } } } 2014/11/17 34
Java Java 设计模式 设计模式 模式的结构的描述与使用 5.应用 Application.java 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(); } 2014/11/17 35
Java Java 设计模式 设计模式 • 具体主题和具体观察者是松耦合关系。由于主题(Subject)接口仅仅依赖于观察者(Observer)接口,因此具体主题只是知道它的观察者是实现观察者(Observer)接口的某个类的实例,但不需要知道具体是哪个类。同样,由于观察者仅仅依赖于主题(Subject)接口,因此具体观察者只是知道它依赖的主题是实现主题(subject)接口的某个类的实例,但不需要知道具体是哪个类。 • 观察模式满足“开-闭原则”。主题(Subject)接口仅仅依赖于观察者(Observer)接口,这样,我们就可以让创建具体主题的类也仅仅是依赖于观察者(Observer)接口,因此如果增加新的实现观察者(Observer)接口的类,不必修改创建具体主题的类的代码。同样,创建具体观察者的类仅仅依赖于主题(Observer)接口,如果增加新的实现主题(Subject)接口的类,也不必修改创建具体观察者类的代码。 三、观察者模式的优点 2014/11/17 36
四、应用举例 • 指挥部希望按时得到水文站测量到的关于水流的信息,比如流量、流速等。
Java Java 设计模式 设计模式 第六章 装饰模式 装饰模式(别名:包装器) 动态地给对象添加一些额外的职责。就功能来说装饰模式相比生成子类更为灵活。 Decorator Pattern(Another Name: Wrapper) Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. 2014/11/17 38
Java Java 设计模式 设计模式 装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。在装饰模式中,“具体组件”类和“具体装饰”类是该模式中的最重要的两个角色。 一 、 概述 2014/11/17 39
Java Java 设计模式 设计模式 假设系统中有一个Bird抽象类以及Bird类的一个子类:Sparrow。 Sparrow类实现了Bird类的fly方法,使得Sparrow类创建的对象 调用fly方法能连续飞行100米。现在用户需要两种鸟,必须分别 能连续飞行150米和200米。 实例 2014/11/17 40
Java Java 设计模式 设计模式 • 装饰模式的结构中包括四种角色: • 抽象组件(Component) • 具体组件(ConcreteComponent) • 装饰(Decorator) • 具体装饰(ConcreteDecotator) 二、装饰模式模式的结构与使用 2014/11/17 41
Java Java 设计模式 设计模式 装饰模式的UML类图 2014/11/17 42
Java Java 设计模式 设计模式 装饰模式的结构的描述与使用 1.抽象组件 : Bird.java public abstract class Bird{ public abstract int fly(); } 2014/11/17 43
Java Java 设计模式 设计模式 装饰模式的结构的描述与使用 2.具体组件 : Sparrow.java public class Sparrow extends Bird{ public final int DISTANCE=100; public int fly(){ return DISTANCE; } } 2014/11/17 44
Java Java 设计模式 设计模式 装饰模式的结构的描述与使用 3.装饰 (Decorator):Decorator.java public abstract class Decorator extends Bird{ protected Bird bird; public Decorator(){ } public Decorator(Bird bird){ this.bird=bird; } } 2014/11/17 45
Java Java 设计模式 设计模式 装饰模式的结构的描述与使用 4.具体装饰(ConcreteDecotator):SparrowDecorator.java public class SparrowDecorator extends Decorator{ public final int DISTANCE=50; //eleFly方法能飞50米 SparrowDecorator(Bird bird){ super(bird); } public int fly(){ int distance=0; distance=bird.fly()+eleFly(); return distance; } private int eleFly(){ //装饰者新添加的方法 return DISTANCE; } } 2014/11/17 46
Java Java 设计模式 设计模式 装饰模式的结构的描述与使用 5.应用 Application.java 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 sparrow=new Sparrow(); Bird sparrowDecorator1= new SparrowDecorator(sparrow); Bird sparrowDecorator2= new SparrowDecorator(sparrowDecorator1); client.needBird(sparrowDecorator1); client.needBird(sparrowDecorator2); } } 2014/11/17 47
Java Java 设计模式 设计模式 • 被装饰者和装饰者是松耦合关系。由于装饰(Decorator)仅仅依赖于抽象组件(Component),因此具体装饰只知道它要装饰的对象是抽象组件的某一个子类的实例,但不需要知道是哪一个具体子类。 • 装饰模式满足“开-闭原则”。不必修改具体组件,就可以增加新的针对该具体组件的具体装饰。 • 可以使用多个具体装饰来装饰具体组件的实例。 三、装饰模式的优点 2014/11/17 48
ReadWord ReadEnglishWord +readWord(File) +readWord(File) 四、应用举例 • 当前系统已有一个抽象类ReadWord,该类有一个抽象方法readWord(),另外还有一个ReadWord类的子类ReadEnglishWord,该类的readWord()方法可以读取一个由英文单词构成的文本文件word.txt。系统已有类的类图如图6.11所示。目前已有一些客户在使用该系统,并使用ReadWord类的对象调用readWord()方法读取文件中的单词。
四、应用举例 • 现有部分用户希望使用ReadWord类的对象调用readWord()方法读取文件word.txt中的单词,并希望同时也能得到该单词 的汉语解释,也有一些用户希望不仅能得到该单词汉语解释也能得到该单词的英文例句。要求不允许修改现有系统的代码以及word.txt文件,对系统进行扩展以满足用户需求。