工厂方法模式(JAVA反射)
模式动机
模式定义
模式结构
模式分析
public abstract class PayMethodFactory
{
public abstract AbstractPay getPayMethod();
}
具体工厂类代码:
public class CashPayFactory extends PayMethodFactory
{
public AbstractPay getPayMethod()
{
return new CashPay();
}
}
客户类代码片段:
PayMethodFactory factory;
AbstractPay payMethod;
factory=new CashPayFactory();
payMethod =factory.getPayMethod();
payMethod.pay();
<?xml version="1.0"?>
<config>
<className>CashPayFactory</className>
</config>
//创建一个字符串类型的对象
Class c = Class.forName(“String”);
Object obj = c.newInstance();
return obj;
工具类XMLUtil代码片段:
//创建DOM文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("config.xml")); //获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode=nl.item(0).getFirstChild();
String cName=classNode.getNodeValue(); //通过类名生成实例对象并将其返回
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
模式实例与解析
实例代码(JAVA):
//抽象产品类 TV
public interface TV
{
public void play();
} //具体产品类 HaierTV
public class HaierTV implements TV
{
public void play()
{
System.out.println("海尔电视机播放中......");
}
} //具体产品类 HisenseTV
public class HisenseTV implements TV
{
public void play()
{
System.out.println("海信电视机播放中......");
}
} //抽象工厂类 TVFactory
public interface TVFactory
{
public TV produceTV();
} //具体工厂类 HaierTVFactory
public class HaierTVFactory implements TVFactory
{
public TV produceTV()
{
System.out.println("海尔电视机工厂生产海尔电视机...");
return new HaierTV();
}
} //具体工厂类 HisenseTVFactory
public class HisenseTVFactory implements TVFactory
{
public TV produceTV()
{
System.out.println("海信电视机工厂生产海信电视机...");
return new HisenseTV();
}
} //配置文件 config.xml
<?xml version="1.0"?>
<config>
<className>HisenseTVFactory</className>
</config> //通过反射获得具体工厂的实例 XMLUtil
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtil
{
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public static Object getBean()
{
try
{
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("config.xml")); //获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode=nl.item(0).getFirstChild();
String cName=classNode.getNodeValue(); //通过类名生成实例对象并将其返回
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
} //客户端 Client
public class Client
{
public static void main(String args[])
{
try
{
TV tv;
TVFactory factory;
factory=(TVFactory)XMLUtil.getBean();
tv=factory.produceTV();
tv.play();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
实例代码(C++):
// 工厂方法模式
#include <iostream>
using namespace std; //抽象产品TV
class TV
{
public:
virtual void play() = 0;
}; //具体产品类 HaierTV
class HaierTV:public TV
{
public:
void play() override
{
cout << "海尔电视机播放中..." << endl;
}
}; //具体产品类HisenseTV
class HisenseTV:public TV
{
public:
void play() override
{
cout << "海信电视机播放中..." << endl;
}
}; //抽象工厂类 TVFactory
class TVFactory
{
public:
virtual TV* productTV() = 0;
}; //具体工厂类 HaierTVFactory
class HaierTVFactory:public TVFactory
{
public:
TV* productTV() override
{
cout << "海尔工厂生产海尔电视机..." << endl;
return new HaierTV();
}
}; //具体工厂类 HisenseTVFactory
class HisenseTVFactory:public TVFactory
{
public:
TV* productTV() override
{
cout << "海信工厂生产海信电视机..." << endl;
return new HisenseTV();
}
}; //客户端
int main()
{
TV* tv = nullptr;
TVFactory* factory = nullptr;
factory = new HaierTVFactory();
tv = factory->productTV();
tv->play();
factory = new HisenseTVFactory();
tv = factory->productTV();
tv->play();
return 0;
}
运行结果:
模式优缺点
模式适用环境
模式应用
(2) Java消息服务JMS(Java Messaging Service) :
//使用上下文和JNDI得到连接工厂的引用,ctx是上下文Context类型的对象
QueueConnectionFactory qConnFact=(QueueConnectionFactory)ctx.lookup("cfJndi");
//使用连接工厂创建一个连接
QueueConnection qConn=qConnFact.createQueueConnection();
//使用连接创建一个会话
QueueSession qSess=qConn.createQueueSession(false,javax.jms.QueueSession. AUTO_ACKNOWLEDGE);
//使用上下文和JNDI得到消息队列的引用
Queue q=(Queue)ctx.lookup("myQueue");
//使用连接创建一个需要发送的消息类型的实例
QueueSender qSend=qSess.createSender(q);
System.out.println("开始发送消息......");
(3) JDBC中的工厂方法:
Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=DB;user=sa;password=");
Statement statement=conn.createStatement();
ResultSet rs=statement.executeQuery("select * from UserInfo");
模式扩展
工厂方法模式(JAVA反射)的更多相关文章
- 设计模式之第1章-工厂方法模式(Java实现)
设计模式之第1章-工厂方法模式(Java实现) “我先来”,“不,老公,我先!”.远远的就听到几个人,哦不,是工厂方法模式和抽象工厂模式俩小夫妻在争吵,尼妹,又不是吃东西,谁先来不都一样(吃货的世界~ ...
- 工厂方法模式--java代码实现
工厂方法模式 工厂方法模式,对简单工厂模式进行了升级.我们将水果园比作一个工厂,在简单工厂模式下,水果园是一个具体的工厂,直接用来生产各种各样的水果.那么在工厂方法模式下,水果园是一个抽象工厂,那么苹 ...
- 设计模式之工厂方法模式(Java实现)
“我先来”,“不,老公,我先!”.远远的就听到几个人,哦不,是工厂方法模式和抽象工厂模式俩小夫妻在争吵,尼妹,又不是吃东西,谁先来不都一样(吃货的世界~).“抽象工厂模式,赶紧的自我介绍,工厂方法模式 ...
- FactoryMethodPattern(工厂方法模式)-----Java/.Net
也就是工厂方法(FactoryMethod)模式允许将产品类的实例化推迟到具体的创建者子类,由创建者子类决定实例化哪一个产品类.我们同样以汽车的生产作为讲解该模式的例子,因为汽车生产从宏观上来说也是特 ...
- Java设计模式(二) 工厂方法模式
本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...
- Java设计模式3:工厂方法模式
工厂方法模式 工厂方法模式是类的创建模式.工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工厂推迟到子类中. 工厂方法模式 工厂方法模式是对简单工厂模式进一步抽象的结果. 假如是不使用反 ...
- 工厂方法模式(Java与Kotlin版)
前文推送 设计模式 简单工厂模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次 ...
- java之设计模式工厂三兄弟之工厂方法模式
[学习难度:★★☆☆☆,使用频率:★★★★★] 简单工厂模式虽然简单,但存在一个很严重的问题.当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码 ...
- Java 设计模式系列(二)简单工厂模式和工厂方法模式
Java 设计模式系列(二)简单工厂模式和工厂方法模式 实现了创建者和调用者的分离.分为:简单工厂模式.工厂方法模式.抽象工厂模式 简单工厂模式.工厂方法模式都很简单,就不详细介绍了. 一.简单工厂 ...
随机推荐
- Centos下安装Oracle12c
总结一次安装oracle的折腾血泪史环境准备 centos7 虚拟机VMware Workstation Pro14 IP:192.168.245.128(根据实际情况) 4G物理内存,8G虚拟内存, ...
- 【你不知道的javaScript 上卷 笔记1】 javaScript 是如何工作的?
一.什么是作用域? 作用域是用来存储变量以及方便寻找变量的一套规则. 二.javaScript 编译过程(编译发生在代码执行前的几微妙) 分词/词法分析(Tokenizing/Lexing)-> ...
- Mariadb Galera Cluster 搭建集群
1.安装MariaDB 和Galera 见另外一篇博客 2.环境修改 2.1 防火墙和SELinux 这里不做说明,参照网上教程,和官方的配置 2.2. 创建用于节点同步的账号 [root@local ...
- C++ log4cpp使用(转)
参考文章: 1.常用C++库(1)日志库 https://blog.csdn.net/qilimi1053620912/article/details/87378707 2.一步步入门log4cpp ...
- Docker最全教程——从理论到实战(十四)
本篇教程主要讲解基于容器服务搭建TeamCity服务,并且完成内部项目的CI流程配置.教程中也分享了一个简单的CI.CD流程,仅作探讨.不过由于篇幅有限,完整的DevOps,我们后续独立探讨. 为了降 ...
- git上传代码技巧
1.一定要先在git上面创建项目然后把文件拉到本地先 1.1克隆到本地(orgin=>'你的远程仓库地址') git clone orgin 1.2初始化项目文件夹 git init 2.操作之 ...
- vue 中的路由为什么 采用 hash 路由模式,而不是href超链接模式(Hypertext,Reference)?
1. vue中路由模式的种类有两种 1. 一种是 hash 模式. 2. 一种是 h5 的 history 模式. 2. hash 和 history 都是来自 bom 对象 bom 来自 windo ...
- 【网站】Kiwi浏览器中文网
2020年1月1日上线 访问地址:http://huangenet.gitee.io/kiwibrowser/
- 后台异常 - sql语句查询出的结果与dao层返回的结果不一致
问题描述 sql语句查询出的结果与dao层返回的结果不一致 问题原因 (1)select 中,查询的列名称重复,数据出现错乱 (2)使用不等号,不等号(!=,<>),查询出来的结果集不包含 ...
- SSM项目中的.tld文件是什么,有什么作用?怎么自定义tld文件
原文链接:https://www.cnblogs.com/guaishoubiubiu/p/8721277.html TLD术语解释:标签库描述文件,如要在JSP页面中使用自定义JSP标签,必须首先定 ...