spring学习中常用到的工厂,抽象工厂学习

news/2024/7/4 1:26:10 标签: spring, string, 产品, import, class, interface
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

 工厂模式有简单工厂模式,工厂方法模式和抽象工厂模式几种形态。其中简单工厂模式和工厂方法模式已经在前面作过介绍。在这里,我们来介绍抽象工厂模式。

  抽象工厂模式是所有形态的工厂模式中最为抽象和最具广泛性的一种形态。

  抽象工厂模式的定义

  抽象工厂模式是工厂方法模式的进一步扩广化和抽象化。我们给出抽象工厂模式的类图定义如下。


       图1. 抽象工厂模式的类图定义


  从上图可以看出,简单工厂模式涉及到以下的角色

   抽象工厂(AbstractFactory)类或接口

   担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何在模式中创立对象的工厂类必须实现这个接口,或继承这个类。

   实工厂类 (Conrete Factory)

   担任这个角色的是与应用程序紧密相关的,直接在应用程序调用下,创立class="tags" href="/tags/ChanPin.html" title=产品>产品实例的那样一些类。

   抽象class="tags" href="/tags/ChanPin.html" title=产品>产品 (Abstract Product)

   担任这个角色的类是工厂方法模式所创立的对象的父类,或它们共同拥有的接口。

   class="tags" href="/tags/ChanPin.html" title=产品>产品 (Concrete Product)

   担任这个角色的类是工厂方法模式所创立的任何对象所属的类。

  怎么这个类图和工厂方法模式的类图看起来是一样的?

  是的,图是一样的,但是含义有很大的不同。必须指出,在抽象工厂模式中,抽象class="tags" href="/tags/ChanPin.html" title=产品>产品 (AbstractProduct) 可能是一个或多个,从而构成一个或多个class="tags" href="/tags/ChanPin.html" title=产品>产品族(Product Family)。 在只有一个class="tags" href="/tags/ChanPin.html" title=产品>产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。在上面的类图中,只给出了一个class="tags" href="/tags/ChanPin.html" title=产品>产品族,相当于位图中的一个点,而完整的位图应当是三维的,如下图。


     图2. 抽象工厂模式的位图

 
  从位图可以清楚地看到,与纸面垂直的数轴,即第三维轴,是代表class="tags" href="/tags/ChanPin.html" title=产品>产品族的数轴。上面的位图中展示的是有两个class="tags" href="/tags/ChanPin.html" title=产品>产品族,族A和族B的情形。

  在只有一个class="tags" href="/tags/ChanPin.html" title=产品>产品族时,第三维就坍缩掉,位图也就只剩下两维。这时抽象工厂模式就退化得与工厂方法模式一模一样。

  在什么情形下应当使用抽象工厂模式

  在以下情况下,应当考虑使用抽象工厂模式。

  首先,一个系统应当不依赖于class="tags" href="/tags/ChanPin.html" title=产品>产品类实例被创立,组成,和表示的细节。这对于所有形态的工厂模式都是重要的。

  其次,这个系统的class="tags" href="/tags/ChanPin.html" title=产品>产品有多于一个的class="tags" href="/tags/ChanPin.html" title=产品>产品族。

  第三,同属于同一个class="tags" href="/tags/ChanPin.html" title=产品>产品族的class="tags" href="/tags/ChanPin.html" title=产品>产品是设计成在一起使用的。这一约束必须得在系统的设计中体现出来。

  最后,不同的class="tags" href="/tags/ChanPin.html" title=产品>产品以一系列的接口的面貌出现,从而使系统不依赖于接口实现的细节。

  其中第二丶第三个条件是我们选用抽象工厂模式而非其它形态的工厂模式的关键性条件。

  抽象工厂模式在小花果园系统中的实现

  现在,我们在佛罗里达的渡假小屋修整好啦。接下来,一项重要而光荣的工作,就是开发小屋后面的小花园。这意味着,我们有两处小花园需要照料,一处在北方地区,另一处在亚热带地区。抽象工厂模式正好适用于我们的情况。


图3. 抽象工厂模式应用于小花果园系统中。三种不同的背景颜色可以区分工厂类,蔬菜类(第一class="tags" href="/tags/ChanPin.html" title=产品>产品族),和水果类的类图(第二class="tags" href="/tags/ChanPin.html" title=产品>产品族)


   两处花园就相当于两个class="tags" href="/tags/ChanPin.html" title=产品>产品族。显然,给北方花园的植物是要种植在一起的,给南方花园的植物是要另种植在一起的。这种分别应当体现在系统的设计上面。这就满足了应当使用抽象工厂模式的第二和第三个条件。

 

相关代码如下:

创建JAVA工程

 

新建三个包:

分别为:factory.impl  存放接口

            factory.action  存放类

            factory.test    测试类

源代码如下:可运行:

 

1. FruitIF 接口

 

package factory.impl;
/**
 * 类说明     水果接口   
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午02:09:11
 */
public interface FruitIF {
 public String getName();
}
 

2.Gardener 接口

package factory.impl;

/**
 * 类说明      园艺爱好者接口类        
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午01:57:59
 */
public interface Gardener {
 
 // 返回蔬菜类接口
 public VeggieIF createVeggie(String name);
 // 返回水果类接口
 public FruitIF createFruit(String name) ;


}

 

3.FruitIF  接口

 

package factory.impl;
/**
 * 类说明     水果接口   
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午02:09:11
 */
public interface FruitIF {
 public String getName();
}

 

 

package factory.action;

class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.FruitIF;

/**
 * 类说明     南方水果实现类   
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午02:14:09
 */
public class NorthernFruit implements FruitIF {
 
 public String name;
 
 public NorthernFruit(String name){
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
 

}
 

package factory.action;

class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.FruitIF;
class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.Gardener;
class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.VeggieIF;

/**
 * 类说明 南方园艺受好者
 *
 * @author zhaoguoli
 * @version v1.0 创建时间:2009-4-10 下午01:59:25
 */
public class NorthernGardener implements Gardener {
 
 // 返回蔬菜类接口
 public VeggieIF createVeggie(String name) {
  return new NorthernVeggie(name);
 }
 // 返回水果类接口
 public FruitIF createFruit(String name) {
  return new NorthernFruit(name);
 }

}

package factory.action;

class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.VeggieIF;

/**
 * 类说明     南方菜实现类       
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午02:11:58
 */
public class NorthernVeggie implements VeggieIF {
 
 private String name;
 
 
 public NorthernVeggie(String name) {
  this.name = name;
 }
 

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
 

}
 

 

package factory.action;

class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.FruitIF;

/**
 * 类说明     北方水果实现类      
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午02:20:57
 */
public class SouthernFruit implements FruitIF {
 
 public String name;
 
 public SouthernFruit(String name){
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
 

}
 

 

package factory.action;

class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.FruitIF;
class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.Gardener;
class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.VeggieIF;

/**
 * 类说明           
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午02:23:52
 */
public class SouthernGardener implements Gardener {
 
 
 // 返回蔬菜类接口
 public VeggieIF createVeggie(String name) {
  return new SouthernVeggie(name);
 }
 // 返回水果类接口
 public FruitIF createFruit(String name) {
  return new SouthernFruit(name);
 }


}
 

package factory.action;

class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.VeggieIF;

/**
 * 类说明     北方菜实现类      
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午02:22:02
 */
public class SouthernVeggie implements VeggieIF {
 
 public String name;
 
 public SouthernVeggie(String name){
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}
 

package factory.test;

class="tags" href="/tags/IMPORT.html" title=import>import factory.action.NorthernGardener;
class="tags" href="/tags/IMPORT.html" title=import>import factory.action.SouthernGardener;
class="tags" href="/tags/IMPORT.html" title=import>import factory.impl.Gardener;

/**
 * 类说明     测试抽象工厂模式        
 * @author   zhaoguoli
 * @version  v1.0  创建时间:2009-4-10 下午02:26:18
 */
public class FactoryTest {

 /**
  * 方法说明:
  * @param args
  */
 public static void main(String[] args) {
  // TODO 自动生成方法存根
  // 南方园艺者生产花和菜
  String name = null;
  // 南方园艺者生产花和菜
  NorthernGardener northernGardener = new NorthernGardener();
  Gardener gardener = (Gardener)northernGardener;
  name = "香蕉";
  System.out.println(northernGardener.createFruit(name).getName());
  name = "南菜";
  System.out.println(northernGardener.createVeggie(name).getName());
  
  // 北方园艺者生产花和菜
  SouthernGardener southernGardener = new SouthernGardener();
  name = "苹果";
  System.out.println(southernGardener.createFruit(name).getName());
  name = "北菜";
  System.out.println(southernGardener.createVeggie(name).getName());

 }

}

 

运行结果如下:

香蕉
南菜
苹果
北菜

 

class="tags" href="/tags/SPRING.html" title=spring>spring使用时,会将园艺者接口中也定义方法,一切尽量用接口。



 


 

 

 


http://www.niftyadmin.cn/n/873933.html

相关文章

按钮隐藏后还可用吗_浏览器隐藏功能,一键管理你的私藏网站!

本文经授权转自「太平洋电脑网」如果几个标签同属于一个网站,将它们分组批量化管理,可以大幅提升浏览效率,这就是Microsoft Edge(Chromium内核)中一项隐藏功能——标签分组Tab Groups。Edge浏览器隐藏的标签分组功能标签分组Tab Groups是Micr…

解决JSP开发Web程序中的中文问题

中文出现?号,即常说的乱码。原因其实很简单,因为大家大多用的是tomcat作为容器,而tomcat服务器的默认编码为 iso-8859-1(西欧字符)。就是因为iso-8859-1(西欧字符)编码造成了我们经常看到?号。方法一:最简单也是用的最…

web开发java中文编码问题

web开发java中文编码问题 关于JSP页面中的pageEncoding和contentType两种属性的区别: pageEncoding是jsp文件本身的编码 contentType的charset是指服务器发送给客户端时的内容编码 JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段…

Cookie域

server端: Java代码 Set-Cookie:domain.test.com key000001 Set-Cookie:domain.test.com path/lsd keytest.com/lsd Set-Cookie:domain.test.com path/lsd/ak47 keytest.com/lsd-ak47 Set-Cookie:domain.test.com path/lsd/lsd keytest.com/lsd-lsd Set-C…

python写前端被嘲讽_python之路-----前端之html协议一

一.概述1.1 什么是html语句?超文本标记语言(Hypertext Markup Language,HTML)通过标签语言来标记要显示的网页中的各个部分。一套规则,浏览器认识的规则浏览器按顺序渲染网页文件,然后根据标记符解释和显示内容。但需要注意的是&a…

必须面对

人生是每个人都无法逃避、必须面对的东西,有的时候人生很苦涩,让人不知道应该如何面对,我也经常不知道应该如何面对,也经常选择逃避,也时不时觉得苦涩,但我想,人生的痛苦其实并非来自于贫穷、挫…

python open函数参数newline_TypeError:“newline”是此函数的无效关键字参数

我写了下面的代码来提取信息。根据文件的第二列对象按字母顺序排列:import csvimport operatorimport sysdef re_sort(in_filebooks.csv, out_filebooks_sort.csv):data csv.reader(open(books.csv, newline), delimiter,)header next(data)sortedlist sorted(da…

软件工程师不可不知的10个概念

出色的软件工程师善用设计模式,勤于代码重构,编写单元测试,并对简单有宗教般的追求。除了这些,优秀的软件工程师还要通晓10个概念,这10个概念超越了编程语言与设计模式,软件工程师应当从更广的范围内明白这…