Java二十三设计模式之------工厂方法模式

一、工厂方法模式(Factory Method)

工厂方法模式有三种

1、普通工厂模式就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图:

举例如下:(我们举一个发送邮件和短信的例子)

首先,创建二者的共同接口:

  1. public interface Sender {  
  2.     public void Send();  
  3. }  

其次,创建实现类:

  1. public class MailSender implements Sender {  
  2.     @Override  
  3.     public void Send() {  
  4.         System.out.println("this is mailsender!");  
  5.     }  
  1. public class SmsSender implements Sender {  
  2.   
  3.     @Override  
  4.     public void Send() {  
  5.         System.out.println("this is sms sender!");  
  6.     }  
  7. }  

最后,建工厂类:

  1. public class SendFactory {  
  2.   
  3.     public Sender produce(String type) {  
  4.         if ("mail".equals(type)) {  
  5.             return new MailSender();  
  6.         } else if ("sms".equals(type)) {  
  7.             return new SmsSender();  
  8.         } else {  
  9.             System.out.println("请输入正确的类型!");  
  10.             return null;  
  11.         }  
  12.     }  
  13. }  

我们来测试下:

  1. public class FactoryTest {  
  2.   
  3.     public static void main(String[] args) {  
  4.         SendFactory factory = new SendFactory();  
  5.         Sender sender = factory.produce("sms");  
  6.         sender.Send();  
  7.     }  
  8. }  

输出:this is sms sender!

2、多个工厂方法模式是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。关系图:

将上面的代码做下修改,改动下SendFactory类就行,如下:

public class SendFactory {  
public Sender produceMail(){  
  1.         return new MailSender();  
  2.     }  
  3.       
  4.     public Sender produceSms(){  
  5.         return new SmsSender();  
  6.     }  
  7. }  

测试类如下:

  1. public class FactoryTest {  
  2.   
  3.     public static void main(String[] args) {  
  4.         SendFactory factory = new SendFactory();  
  5.         Sender sender = factory.produceMail();  
  6.         sender.Send();  
  7.     }  
  8. }  

输出:this is mailsender!

2.2、静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

  1. public class SendFactory {  
  2.       
  3.     public static Sender produceMail(){  
  4.         return new MailSender();  
  5.     }  
  6.       
  7.     public static Sender produceSms(){  
  8.         return new SmsSender();  
  9.     }  
  10. }  
[java] view plaincopy
  1. public class FactoryTest {  
  2.   
  3.     public static void main(String[] args) {      
  4.         Sender sender = SendFactory.produceMail();  
  5.         sender.Send();  
  6.     }  
  7. }  

输出:this is mailsender!

总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

3、抽象工厂模式(Abstract Factory)

工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。因为抽象工厂不太好理解,我们先看看图,然后就和代码,就比较容易理解。

请看例子:

  1. public interface Sender {  
  2.     public void Send();  
  3. }  

两个实现类:

  1. public class MailSender implements Sender {  
  2.     @Override  
  3.     public void Send() {  
  4.         System.out.println("this is mailsender!");  
  5.     }  
  1. public class SmsSender implements Sender {  
  2.   
  3.     @Override  
  4.     public void Send() {  
  5.         System.out.println("this is sms sender!");  
  6.     }  
  7. }  

两个工厂类:

  1. public class SendMailFactory implements Provider {  
  2.       
  3.     @Override  
  4.     public Sender produce(){  
  5.         return new MailSender();  
  6.     }  
  1. public class SendSmsFactory implements Provider{  
  2.   
  3.     @Override  
  4.     public Sender produce() {  
  5.         return new SmsSender();  
  6.     }  
  7. }  

在提供一个接口:

  1. public interface Provider {  
  2.     public Sender produce();  
  3. }  

测试类:

  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.         Provider provider = new SendMailFactory();  
  5.         Sender sender = provider.produce();  
  6.         sender.Send();  
  7.     }  
  8. }  

其实这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!

以上内容引自于   https://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html

转载于:https://www.cnblogs.com/wuxinyiwu/p/8057645.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453388.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无法转化为项目财富的技术或功能就是垃圾

技术人员可能有个习惯,也可以叫通病,发现一个新技术,或者新的想法,会把某个现有的东西做的更好,或者可以增加某个功能让系统看上去更完美。 如果这是一个产品,那么大家都会鼓励你去做,如果我们…

ibatis oracle function,IBATIS调用oracle function(函数)的步骤实例

IBATIS调用oracle function(函数)的方法实例引用create or replace function getClassifiedCode(p_planCode in varchar2 -- 险种代码,p_usageAttributeCode in varchar2 -- 使用性质代码,p_ownershipAttributeCode in varchar2 -- 所属性质代码,p_vehicleTypeCode in varchar2…

一元多项式乘法算法

我认为大致算法应该是这样的: 首先准备一个空的链表L。利用第一个多项式的的指针所指的节点数值乘以多项式二的每一项,将结果保存在链表L中。 然后将指向该节点的指针后移到下一个节点继续进行乘法运算,将所得结果加到L中(这个操作已经在一…

堆以及stl堆的使用

概念 性质: 1.堆是一颗完全二叉树,用数组实现。    2.堆中存储数据的数据是局部有序的。 最大堆:1.任意一个结点存储的值都大于或等于其任意一个子结点中存储的值。      2.根结点存储着该树所有结点中的最大值。 最小堆:1.任意一个结…

读【36岁IT老人再次随笔】的读后感,你会哪些计算机语言?

论坛首页一篇:社区“揭穿最大谎言”事件 , 我看了,也顺便看了里面另一位仁兄的【36岁IT老人再次随笔】 其中关键的地方就是一个例子:你会哪些计算机语言? 这个问题很有意思,确实如网友回复里说到的&#xf…

php接收vue请求数据axios,详解vue axios用post提交的数据格式

Content-type的几种常见类型一、是什么?是Http的实体首部字段,用于说明请求或返回的消息主体是用何种方式编码,在request header和response header里都存在。二、几个常用类型:1、application/x-www-form-urlencoded这应该是最常见…

数据结构中的逻辑结构简介

数据的逻辑结构是对数据之间关系的描述,有时就把逻辑结构简称为数据结构。逻辑结构形式地定义为(K,R)(或(D,S)),其中,K是数据元素的有限集&#x…

applicationContext配置文件模板1

<?xml version"1.0" encoding"utf-8"?> <beans      --整个配置文件的根节点&#xff0c;包含一个或多个bean元素 xmlns    --最基本的命名空间定义 xmlns:xsi  --最基本的命名空间定义 xmlns:context  --启动自动扫描或注解装配…

时间复杂度的一些计算规则

一些规则(引自&#xff1a;时间复杂度计算 ) 1) 加法规则 T(n,m) T1(n) T2(n) O (max ( f(n),g(m) ) 2) 乘法规则 T(n,m) T1(n) * T2(m) O (f(n) * g(m)) 3) 一个特例&#xff08;问题规模为常量的时间复杂度&#xff09; 在大O表示法里面有一个特例&#xff0c;如…

职场新人面试误区:我的技术好,所以你必须要请我?

这个是论坛的一个帖子。 前几天有家软件公司联系到我&#xff0c;去之前电话里跟他们的项目经理聊了两句&#xff0c;什么都明白了就没去面试 是老板先给我打的电话&#xff0c;问我做J2EE多久了&#xff0c;期望薪水什么个范围。。。 然后老板说&#xff0c;你稍等&#xff…

Oracle 基础

为什么80%的码农都做不了架构师&#xff1f;>>> Oracle DB笔录&#xff0c;以后会不断Add&#xff0c;欢迎留言补充! --cmd.exe(你懂得!) --[1]多个数据库实例&#xff0c;切换选择DB后&#xff0c;登录操作 set ORACLE_SIDorcl --选择DB orcl(你的DB实例名) --可在…

Linux执行命令提示Password,linux expect远程自动登录以及执行命令

linux远程自动登录以及执行命令远程登录该自动登录的过程是通过shell里面expect实现的&#xff0c;类似相当于开了一个类似于cmd的命令段输出IP和密码。注意该脚本能够执行的前提是安装了expectyum install -y expect直接上脚本&#xff1a;#!/usr/bin/expect …

双塔

## 双塔 题目描述 有n个数字&#xff0c;要求将这n个数字分成两部分&#xff08;两部分可以数字个数不同&#xff09;&#xff0c;使得两部分数字之和的差最小 输入输出格式 输入&#xff1a; 第一行为n 第二行有n个数&#xff0c;即题目中所描述那样 输出&#xff1a; 两部分和…

时间复杂度计算杂记

算法时间复杂度的计算 [整理] 时间复杂度算法 基本的计算步骤 时间复杂度的定义 一般情况下&#xff0c;算法中基本操作重复执行的次数是问题规模n的某个函数&#xff0c;用T(n)表示&#xff0c;若有某个辅助函数f(n)&#xff0c;使得当n趋近于无穷大时&#xff0c;T(n)/f(n…

MyBatis 在xml文件中处理大于号小于号的方法

为什么80%的码农都做不了架构师&#xff1f;>>> 第一种方法&#xff1a;用转义字符&#xff08;注&#xff1a;对大小写敏感&#xff01; &#xff09; 用了转义字符把>和<替换掉&#xff0c;然后就没有问题了。 SELECT * FROM test WHERE 1 1 AND start_da…

linux 进程间读写锁,Linux系统编程—进程间同步

我们知道&#xff0c;线程间同步有多种方式&#xff0c;比如&#xff1a;信号量、互斥量、读写锁&#xff0c;等等。那进程间如何实现同步呢&#xff1f;本文介绍两种方式&#xff1a;互斥量和文件锁。##互斥量mutex我们已经知道了互斥量可以用于在线程间同步&#xff0c;但实际…

程序员:开汽车,难道我要知道汽车的原理才能把车开好吗?

一个网友的迷惑&#xff1a; 我工作&#xff15;年了&#xff0c;一直做&#xff2a;&#xff12;&#xff25;&#xff25;的项目&#xff0c;前几天去面试&#xff0c;一个人问我JDBC有几种连接方式&#xff0c;这个问题这么多年以来我从来没有遇见过&#xff0c;不知道大家 …

杭州某知名xxxx公司急招大量java以及大数据开发工程师

因公司战略以及业务拓展&#xff0c;收大量java攻城狮以及大数据开发攻城狮. 职位信息&#xff1a; java攻城狮: https://job.cnblogs.com/offer/56032 大数据开发攻城狮: https://job.cnblogs.com/offer/56033 欢迎博客园的XDJM自荐和推荐&#xff01; 此招聘长期有效 欢迎留言…

35.6. /etc/dnsmasq.d/dnsmasq.address.conf

vim /etc/dnsmasq.d/dnsmasq.address.confaddress/www.mydomain.com/172.16.0.254deny domain address/www.facebook.com/127.0.0.1 address/www.google.com/127.0.0.135.6.1. 域名劫持 将域名解析到错误的地址&#xff0c;这样可以屏蔽一些网站。 address/www.facebook.com/12…

请求地址操作中的(int*)

例如 float b3.14,*a&b; int *p(int *)a; 表示将指针a的类型转换为整型指针再赋给p。