JAVA 设计模式
时间:2010-09-21 来源:ilex
JAVA 设计模式
模板模式 Template 类型:行为模式 模板方法模式定义一个操作中算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 【模板方法模式-JAVA代码实现】 新建赛车的父类: package car_package; public class car_parent { private int speed; public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } public void print_speed() { System.out.println("将速度" + this.getSpeed() + "取出来!"); } } 新建红色仪表盘的赛车实现类: package car_imple; import car_package.car_parent; public class car_imple_red extends car_parent { @Override public void print_speed() { super.print_speed(); System.out.println("将速度" + this.getSpeed() + "用红色的仪表盘显示车的速度"); } } 新建蓝色仪表盘的赛车实现类: package car_imple; import car_package.car_parent; public class car_imple_blue extends car_parent { @Override public void print_speed() { super.print_speed(); System.out.println("将速度" + this.getSpeed() + "用蓝色的仪表盘显示车的速度"); } } 新建客户端运行类: package run_main; import car_imple.car_imple_blue; import car_imple.car_imple_red; import car_package.car_parent; public class run_main { public static void main(String[] args) { car_parent car_ref_red = new car_imple_red(); car_ref_red.setSpeed(300); car_ref_red.print_speed(); car_parent car_ref_blue = new car_imple_blue(); car_ref_blue.setSpeed(400); car_ref_blue.print_speed(); } } 程序运行结果如下: 将速度300取出来! 将速度300用红色的仪表盘显示车的速度 将速度400取出来! 将速度400用蓝色的仪表盘显示车的速度 这就是模板方法模式,一个最常用,最容易理解的一个模式,将相同的功能抽象出来成一个父类,然后用子类做不同功能的实现 观察者模式 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让他们能够自动更新自己 观察者模式的组成 1.抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类或接口来实现 2.抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。 3.具体主题角色(Watched):把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类或接口来实现。 4.具体观察者角色(Watcher):为所有具体的观察者定义一个接口,在得到主题的通知时更新自己 A.自定义观察者模式 例如: 1.抽象主题角色类 Java代码 package com.observe; public interface AbstractWatched { //增加一个观察者 public void addAbstactWatcher(AbstractWatcher watcher); //移除一个观察者 public void removeAbstactWatcher(AbstractWatcher watcher); //移除所有的观察着 public void removeAll(); //通知所有的观察者 public void notifyWatchers(); } 2.抽象观察者角色 Java代码 package com.observe; public interface AbstractWatcher { public void update(); } 3.具体主题角色(Watched) Java代码 package com.observe; import java.util.ArrayList; import java.util.List; public class ConcreteWatched implements AbstractWatched { //list:存放观察者的一个集合对象 List<AbstractWatcher> list = new ArrayList<AbstractWatcher>(); //增加一个观察者 public void addAbstactWatcher(AbstractWatcher watcher) { list.add(watcher); } //移除一个观察者 public void removeAbstactWatcher(AbstractWatcher watcher) { list.remove(watcher); } //移除所有的观察着 public void removeAll() { list.clear(); } //通知所有的观察者 public void notifyWatchers() { for(AbstractWatcher watcher : list){ watcher.update(); } } } 4.具体观察者角色(Watcher) Java代码 package com.observe; public class ConcreteWatcher implements AbstractWatcher { //观察到被观察者发生变化时,执行的方法 public void update() { System.out.println("update....."); } } 5.客户端调用: Java代码 package com.observe; public class ClientTest { public static void main(String[] args){ //定义一个被观察者对象 AbstractWatched watched = new ConcreteWatched(); //定义三个观察者对象 AbstractWatcher watcher1 = new ConcreteWatcher(); AbstractWatcher watcher2 = new ConcreteWatcher(); AbstractWatcher watcher3 = new ConcreteWatcher(); //被观察者添加观察者. 被观察者和观察者之间关系是一对多关系 watched.addAbstactWatcher(watcher1); watched.addAbstactWatcher(watcher2); watched.addAbstactWatcher(watcher3); System.out.println("第1次..."); //被观察者发生改变时,通知观察者执行相应方法 watched.notifyWatchers(); //移除一个观察者 watched.removeAbstactWatcher(watcher2); System.out.println("第2次..."); //被观察者发生改变时,通知观察者执行相应方法 watched.notifyWatchers(); //移除一个所有观察者 watched.removeAll(); System.out.println("第3次..."); //被观察者发生改变时,通知观察者执行相应方法 watched.notifyWatchers(); } } 执行结果为: 第1次... update..... update..... update..... 第2次... update..... update..... 第3次... 门面模式(外观模式): 定义:它为子系统中的一组接口提供一个统一的高层接口。是的子系统更容易使用。 有一天女朋友想要去一个地方旅游。。旅游需要考虑很多很多的问题。如旅游的地点,航班,宾馆,饭店。我把所有的这些问题都扔给她了。。。假设简化旅游的行程。需要完成的步骤有 计划旅游景点 预定宾馆 预定机票 飞往目的地 入住宾馆 吃饭 游玩 首先把旅游作为一个子系统,子系统包含4个类 ,分别如下。 航班 Java代码 package facade.demo; /** * 航班 * @author Nicholas * */ public class Flight { public void scheduled(){ System.out.println("预定机票"); } public void go(){ System.out.println("飞往目的地"); } } package facade.demo; /** * 航班 * @author Nicholas * */ public class Flight { public void scheduled(){ System.out.println("预定机票"); } public void go(){ System.out.println("飞往目的地"); } } 宾馆 Java代码 package facade.demo; /** * 宾馆 * @author Nicholas * */ public class Hotel { public void booking(){ System.out.println("预定宾馆"); } public void check(){ System.out.println("入住宾馆"); } } package facade.demo; /** * 宾馆 * @author Nicholas * */ public class Hotel { public void booking(){ System.out.println("预定宾馆"); } public void check(){ System.out.println("入住宾馆"); } } 旅游景点 Java代码 package facade.demo; /** * 旅游景点 * @author Nicholas * */ public class Place { public void plan(){ System.out.println("计划旅游景点"); } public void play(){ System.out.println("游玩"); } } package facade.demo; /** * 旅游景点 * @author Nicholas * */ public class Place { public void plan(){ System.out.println("计划旅游景点"); } public void play(){ System.out.println("游玩"); } } 饭店 Java代码 package facade.demo; /** * 饭店 * @author Nicholas * */ public class Restaurant { public void eating(){ System.out.println("吃饭"); } } package facade.demo; /** * 饭店 * @author Nicholas * */ public class Restaurant { public void eating(){ System.out.println("吃饭"); } } 好了。。旅游真是个麻烦事情,我还是把这些麻烦扔给女朋友吧。。 女朋友 Java代码 package facade.demo; /** * 我的女朋友 * @author Nicholas * */ public class Mygirl1 { private Flight flight; private Hotel hotel; private Place place; private Restaurant restaurant; public Mygirl1(Flight flight, Hotel hotel, Place place, Restaurant restaurant) { this.flight = flight; this.hotel = hotel; this.place = place; this.restaurant = restaurant; } public void travel(){ place.plan(); hotel.booking(); flight.scheduled(); flight.go(); hotel.check(); restaurant.eating(); place.play(); } public static void main(String[] args){ Flight flight = new Flight(); Hotel hotel = new Hotel(); Place place = new Place(); Restaurant restaurant = new Restaurant(); Mygirl1 mygirl = new Mygirl1(flight,hotel,place,restaurant); mygirl.travel(); } } package facade.demo; /** * 我的女朋友 * @author Nicholas * */ public class Mygirl1 { private Flight flight; private Hotel hotel; private Place place; private Restaurant restaurant; public Mygirl1(Flight flight, Hotel hotel, Place place, Restaurant restaurant) { this.flight = flight; this.hotel = hotel; this.place = place; this.restaurant = restaurant; } public void travel(){ place.plan(); hotel.booking(); flight.scheduled(); flight.go(); hotel.check(); restaurant.eating(); place.play(); } public static void main(String[] args){ Flight flight = new Flight(); Hotel hotel = new Hotel(); Place place = new Place(); Restaurant restaurant = new Restaurant(); Mygirl1 mygirl = new Mygirl1(flight,hotel,place,restaurant); mygirl.travel(); } } 结果如下: 计划旅游景点 预定宾馆 预定机票 飞往目的地 入住宾馆 吃饭 游玩 以上都是我的想象了。。。女朋友就是上帝啊。。。。。哎。如果真的那样做。。估计女朋友非弄死我。。。 到这里我们发现了个问题。女朋友要旅游需要关心那么多问题。。这些对她来说太复杂了。。她并不关心细节。只要她答到旅游的目的就好了。。。这时候,解决麻烦的人出现了。。。对,那就好我,我就是那个所谓的"外观"。我来把这些问题解决掉,让她享受旅游的过程就好了。 我 Java代码 package facade.demo; /** * 我(我就是外观了) * @author Nicholas * */ public class ManFacade { private Flight flight; private Hotel hotel; private Place place; private Restaurant restaurant; public ManFacade(){ this.flight = new Flight(); this.hotel = new Hotel(); this.place = new Place(); this.restaurant = new Restaurant(); } public ManFacade(Flight flight, Hotel hotel, Place place, Restaurant restaurant) { this.flight = flight; this.hotel = hotel; this.place = place; this.restaurant = restaurant; } public void travel(){ place.plan(); hotel.booking(); flight.scheduled(); flight.go(); hotel.check(); restaurant.eating(); place.play(); } } package facade.demo; /** * 我(我就是外观了) * @author Nicholas * */ public class ManFacade { private Flight flight; private Hotel hotel; private Place place; private Restaurant restaurant; public ManFacade(){ this.flight = new Flight(); this.hotel = new Hotel(); this.place = new Place(); this.restaurant = new Restaurant(); } public ManFacade(Flight flight, Hotel hotel, Place place, Restaurant restaurant) { this.flight = flight; this.hotel = hotel; this.place = place; this.restaurant = restaurant; } public void travel(){ place.plan(); hotel.booking(); flight.scheduled(); flight.go(); hotel.check(); restaurant.eating(); place.play(); } } 看来麻烦解决掉了。女朋友很轻松的享受旅游过程了。。。。 Java代码 package facade.demo; /** * 女朋友 * @author Nicholas * */ public class Mygirl { public static void main(String[] args){ Restaurant restaurant = new Restaurant(); ManFacade manFacade = new ManFacade();//我来解决掉这些麻烦。。。 manFacade.travel();//旅游成功 } } package facade.demo; /** * 女朋友 * @author Nicholas * */ public class Mygirl { public static void main(String[] args){ Restaurant restaurant = new Restaurant(); ManFacade manFacade = new ManFacade();//我来解决掉这些麻烦。。。 manFacade.travel();//旅游成功 } } 结果如下: 计划旅游景点 预定宾馆 预定机票 飞往目的地 入住宾馆 吃饭 游玩 本身外观模式的作用就是让接口更容易使用。真实的场景要复杂的多,这个例子只能提供个表面的意思。 总的来说,外观模式就是为了使接口更简单。。。 工厂模式 工厂模式主要是为创建对象提供了接口。主要包括三类:简单工厂模式,工厂方法模式和抽象工厂模式。 1.简单工厂模式:模式很简单,使用在业务较简单的情况。由三种角色构成,分别是工厂类角色,抽象产品角色以及具体产品角色。其中工厂类是核心,包含一定的逻辑判断,而抽象产品角色是由一个抽象类或接口实现,而具体产品则是对抽象产品的实现。 下面写了一个程序实现简单工厂模式:其中抽象产品角色为一个接口Industry.java(行业),具体产品角色为两个ITIndustry.java(IT行业)和FinanceIndustry.java(金融行业),工厂类为IndustryFactory.java,最后是一个测试类SimpleFactoryTest.java。 Industry.java: package com.xpec.landon.trainjava.oop; /** * 一个普通的接口,行业 * @author lvwenyong * */ public interface Industry { void getIndustry(); } ITIndustry.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /** * 简单工厂模式中的具体产品-IT行业 * @author lvwenyong * */ public class ITIndustry implements Industry{ public void getIndustry() { System.out.println("My industry is IT!"); } } FinanceIndustry.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /** * 简单工厂模式中的具体产品-金融行业 * @author lvwenyong * */ public class FinanceIndustry implements Industry{ public void getIndustry() { System.out.println("My industry is Finance!"); } } IndustryFactory.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /** * 简单工厂模式中的工厂类-行业管理工厂 * 简单工厂模式的弊端在于每增加一个行业,都需要在工厂类中添加相应的逻辑,所以需要引入工厂方法模式 * @author lvwenyong * */ public class IndustryFactory { public Industry createIndustry(String type) { if(type.equals("IT")) { return (new ITIndustry()); } else if(type.equals("Finance")) { return (new FinanceIndustry()); } else { return null; } } } SimpleFactoryTest.java: package com.xpec.landon.trainjava.designpattern; /** * 简单工厂模式的测试 * @author lvwenyong * */ public class SimpleFactoryTest { public static void main(String[] args) { IndustryFactory factory = new IndustryFactory(); factory.createIndustry("IT").getIndustry(); factory.createIndustry("Finance").getIndustry(); } } 2.工厂方法模式:简单工厂模式的弊端在于每增加一个行业,都需要在工厂类中增加相应的逻辑,所以需要引入工厂方法模式。工厂方法模式与简单工厂模式不同的是将原有的工厂类划分为抽象工厂和具体工厂。其中抽象工厂提供了一个接口,具体工厂负责实现对应的具体的产品。 下面写了一个程序实现抽象方法模式:其中抽象工厂为IndustryFactoryInterface.java,包括两个具体工厂ITIndustryFactory.java和FinanceIndusryFactory.java,具体的产品还是ITIndustry.java和FinanceIndustry.java。另外还有一个测试类FactoryMethodTest.java。 IndustryFactoryInterface.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /* * 工厂方法模式中的抽象工厂角色 */ public interface IndustryFactoryInterface { public Industry createIndustry(); } ITIndustryFactory.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /** * 工厂方法模式中的具体工厂角色-IT行业工厂 * @author lvwenyong * */ public class ITIndustryFactory implements IndustryFactoryInterface{ public Industry createIndustry () { return new ITIndustry(); } } FinanceIndustry.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /** * 工厂方法模式中的具体工厂角色-金融行业工厂 * @author lvwenyong * */ public class FinanceIndustryFactory implements IndustryFactoryInterface{ public Industry createIndustry() { return (new FinanceIndustry()); } } 具体的产品类同上简单工厂模式。 FactoryMethodTest.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /** * 工厂方法模式测试 * @author lvwenyong * */ public class FactoryMethodTest { public static void main(String[] args) { //首先得到具体的工厂,然后生产 IndustryFactoryInterface factoryInterface1 = new ITIndustryFactory(); Industry itIndustry = factoryInterface1.createIndustry(); itIndustry.getIndustry(); IndustryFactoryInterface factoryInterface2 = new FinanceIndustryFactory(); Industry financeIndustry = factoryInterface2.createIndustry(); financeIndustry.getIndustry(); } } 3.抽象工厂模式:抽象工厂模式是一种比工厂模式抽象程度更高的模式。在工厂方法模式中,一个具体的工厂类负责创建一个单独的产品,如果有两个不同的产品要创建,就需要两个不同的工厂类,即使这两个产品有某些必要联系,同样还是需要两个不同的工厂类。 所以说工厂方法模式是针对于一个产品系列的,而抽象工厂模式是针对多个产品系列的。即工厂方法模式是一个产品一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。 下面写了一个程序实现抽象工厂模式:其中包括抽象工厂AbstractFactory.java,负责创建行业和公司。还包括两个具体工厂FactoryA.java和FactoryB.java。另外为了配合使用抽象工厂模式,又创建了一个接口Company.java,并有两个具体的MicosoftCompany.java和GoldmanCompany.java。最后还有一个测试类AbstractFactory.java。 AbstractFactory.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /** * 抽象工厂中模式中的抽象工厂 * @author lvwenyong * */ public interface AbstractFatory { public Industry createIndustry(); public Company createCompany(); } FactoryA.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.*; /** * 抽象工厂模式中的具体工厂 * @author lvwenyong * */ public class FactoryA implements AbstractFatory{ public Industry createIndustry() { return new ITIndustry(); } public Company createCompany() { return new MicrosoftCompany(); } } FactoryB.java: package com.xpec.landon.trainjava.designpattern; import com.xpec.landon.trainjava.oop.Industry; /** * 抽象工厂模式中的具体工厂 * @author lvwenyong * */ public class FactoryB implements AbstractFatory{ public Industry createIndustry() { return new FinanceIndustry(); } public Company createCompany() { return new GoldmanCompany(); } } Company.java: package com.xpec.landon.trainjava.designpattern; /** * 一个接口,公司:为了配合使用抽象工厂模式 * 作为抽象产品 * @author lvwenyong * */ public interface Company { void getCompany(); } MicosoftCompany.java: package com.xpec.landon.trainjava.designpattern; /** * 抽象工厂模式中的一个具体产品:微软 */ public class MicrosoftCompany implements Company{ public void getCompany() { System.out.println("My company is Mircosoft!"); } } GoldmanCompany.java: package com.xpec.landon.trainjava.designpattern; /** * 抽象工厂模式中的一个具体产品:高盛 */ public class GoldmanCompany implements Company{ public void getCompany() { System.out.println("My company is Goldman Sachs!"); } } AbstractFactoryTest.java: package com.xpec.landon.trainjava.designpattern; /** * 抽象工厂模式测试 * @author lvwenyong * */ public class AbstractFactoryTest { public static void main(String[] args) { FactoryA fa = new FactoryA(); FactoryB fb = new FactoryB(); fa.createIndustry().getIndustry(); fa.createCompany().getCompany(); fb.createIndustry().getIndustry(); fb.createCompany().getCompany(); } } ITIndustry.java和FinaceIndustry.java同上面。 相关阅读 更多 +