工厂模式学习
来源:互联网 发布:阿里云如何解析域名 编辑:程序博客网 时间:2024/06/05 00:11
以下是我学习尚学堂视频DRP项目关于工厂模式的总结,继续更新中...
1.最原始的工厂模式:--业务逻辑无接口: drp_my1.5.3.4
1.Dao层接口
public interface ItemDao {
public void addItem(Connection conn,Item item);
}
2.Dao实现:
public class ItemDao4MySqlImpl implements ItemDao {
public void addItem(Connection conn, Item item) {
}
}
3.工厂接口:
public interface ItemDaoFactory {
public ItemDao createItemDao();
}
4.工厂实现:
public class ItemDao4MySqlFactory implements ItemDaoFactory {
public ItemDao createItemDao() {
return new ItemDao4MySqlImpl();
}
}
5.业务逻辑:
public class ItemManager {
private ItemDaoFactory itemDaoFactory ;
private static ItemManager instance = new ItemManager();
private ItemManager() {
itemDaoFactory = new ItemDao4MySqlFactory();
}
public static ItemManager getInstance () {
return instance;
}
public void addItem(Item item) {
Connection conn = DB.getConnection();
this.itemDaoFactory.createItemDao().addItem(conn, item);
DB.close(conn);
}
}
总结:业务逻辑类没有接口,采用单例模式创建.当初始化业务逻辑类时,创建出具体的工厂实现类.
缺点:如果要更换别的数据库,需要在构造函数里手动更改具体的工厂实现类.
_____________________________________________________________________________________
2.对业务逻辑层进一步改进: --读取配置文件,放在构造函数里: drp_my1.5.3.4
1.Dao层接口
public interface ItemDao {
public void addItem(Connection conn,Item item);
}
2.Dao实现:
public class ItemDao4MySqlImpl implements ItemDao {
public void addItem(Connection conn, Item item) {
}
}
3.工厂接口:
public interface ItemDaoFactory {
public ItemDao createItemDao();
}
4.工厂实现:
public class ItemDao4MySqlFactory implements ItemDaoFactory {
public ItemDao createItemDao() {
return new ItemDao4MySqlImpl();
}
}
5.业务逻辑:
public class ItemManager {
private ItemDaoFactory itemDaoFactory ;
private static ItemManager instance = new ItemManager();
private ItemManager() {
Properties props = this.loadProp();
String className = props.getProperty("item-dao-factory");
itemDaoFactory = (ItemDaoFactory)Class.forName(className).newInstance();
}
public static ItemManager getInstance () {
return instance;
}
public void addItem(Item item) {
Connection conn = DB.getConnection();
this.itemDaoFactory.createItemDao().addItem(conn, item);
DB.close(conn);
}
}
改进:初始化业务逻辑类时创建出的工厂实现类由读取配置文件动态生成.
只要更改配置文件就能为我们创建出需要的工厂实现类.
缺点:读取配置文件的代码都放在构造函数里.应该被分离出来.
_____________________________________________________________________________________
3.标准的工厂模式:--(需要传Connection) drp_my1.7(ItemManagerImpl)
1.Dao层接口
public interface ItemDao {
public void addItem(Connection conn,Item item);
}
2.Dao实现:
public class ItemDao4MySqlImpl implements ItemDao {
public void addItem(Connection conn, Item item) {
}
}
3.工厂接口:
public interface ItemDaoFactory {
public ItemDao createItemDao();
}
4.工厂实现:
public class ItemDao4MySqlFactory implements ItemDaoFactory {
public ItemDao createItemDao() {
return new ItemDao4MySqlImpl();
}
}
5.业务逻辑接口:
public interface ItemManager {
public void addItem(Item item);
}
6.业务逻辑实现:
public class ItemManagerImpl implements ItemManager{
private ItemDaoFactory itemDaoFactory ;
public ItemManagerImpl(ItemDaoFactory itemDaoFactory) {
this.itemDaoFactory = itemDaoFactory;
}
public void addItem(Item item) {
Connection conn = DB.getConnection();
this.itemDaoFactory.createItemDao().addItem(conn, item);
DB.close(conn);
}
}
7.读取配置文件: InitServlet
public class InitServlet extends HttpServlet {
public void init() {
String className = props.getProperty("item-dao-factory");
ItemDaoFactory itemDaoFactory = (ItemDaoFactory)Class.forName(className).newInstance();
ItemManager itemManager = new ItemManagerImpl(itemDaoFactory);
this.getServletContext().setAttribute(ItemManager.class.getName(), itemManager);
}
改进:分离出了业务逻辑接口和实现.当Web容器启动时,读取配置文件,把具体的工厂创建出来,
传给业务逻辑实现类,同时暴露给JSP的是业务逻辑接口.
缺点:工厂类太多了,每个工厂都有实现类.工厂泛滥.
________________________________________________________________________________________________
4.简化了的工厂1:只有一个工厂类,Dao层不传递Connection drp_my1.7(FlowCard)
1.Dao层接口
public interface FlowCardDao {
public void addFlowCardMaster(FlowCard flowCard)
}
2.Dao实现:
public class FlowCardDao4MySqlImpl implements FlowCardDao {
public void addFlowCardMaster(FlowCard flowCard){
Connection conn = ConnectionManager.getConnection();
.......
//close pstmt,don't close connection
}
}
3.工厂类:
public class FlowCardDaoFactory {
private static FlowCardDaoFactory instance = new FlowCardDaoFactory();
private FlowCardDaoFactory() {}
public static FlowCardDaoFactory getInstance() {
return instance;
}
public FlowCardDao createFlowCardDao() {
return new FlowCardDao4MySqlImpl(); //直接创建产品,写死了.
}
}
4.业务逻辑接口:
public interface FlowCardService {
public void addFlowCard(FlowCard flowCard);
}
5.业务逻辑实现:
public class FlowCardServiceImpl implements FlowCardService {
private FlowCardDao flowCardDao;
public FlowCardServiceImpl(FlowCardDao flowCardDao) {
this.flowCardDao = flowCardDao;
}
public void addFlowCard(FlowCard flowCard){
Connection conn = ConnectionManager.getConnection();
conn.setAutoCommit(false);
//因为依赖于Dao接口,直接调用Dao层的方法
flowCardDao.addFlowCardMaster(flowCard);
conn.commit();
conn.rollback();
conn.setAutoCommit(true);
ConnectionManager.closeConnection();
}
}
6.读取配置文件: InitServlet
public class InitServlet extends HttpServlet {
public void init() {
FlowCardDao flowCardDao = FlowCardDaoFactory.getInstance().createFlowCardDao();
FlowCardService flowCardService = new FlowCardServiceImpl(flowCardDao);
this.getServletContext().setAttribute("flowCardService", flowCardService);
}
}
7.封装Connection:
public class ConnectionManager {
private static ThreadLocal connectionHolder = new ThreadLocal();
public static Connection getConnection() {
Connection conn = (Connection)connectionHolder.get();
if (conn == null) {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/drp", "root", "root");
connectionHolder.set(conn);
}
}
return conn;
}
总结:工厂类直接来创建产品.业务逻辑实现类不再依赖与工厂接口,依赖于Dao接口,
同业务层依赖于工厂接口一样,传给业务层构造函数的是Dao接口,但是需要new出具体的Dao产品.
_____________________________________________________________________________________________
4.简化工厂2:动态代理统一管理事务.在业务逻辑方法中不再管理事务,业务层依赖于Dao. drp_my1.7
public Object invoke(Object proxy, Method method, Object[] args){
Object ret = null;
Connection conn = ConnectionManager.getConnection();
conn.setAutoCommit(false);
ret = method.invoke(this.targetObject, args);
conn.commit();
conn.rollback();
ConnectionManager.closeConnection();
return ret;
}
5.业务逻辑方法:
public void addFlowCard(FlowCard flowCard){
//因为依赖于Dao接口,直接调用Dao层的方法
flowCardDao.addFlowCardMaster(flowCard);
}
6.读取配置文件: InitServlet
public class InitServlet extends HttpServlet {
public void init() {
FlowCardDao flowCardDao = FlowCardDaoFactory.getInstance().createFlowCardDao();
//FlowCardService flowCardService = new FlowCardServiceImpl(flowCardDao);
TransactionHandler transactionHandler = new TransactionHandler();
FlowCardService flowCardService = (FlowCardService)
transactionHandler.newProxy(new FlowCardServiceImpl(flowCardDao));
this.getServletContext().setAttribute(FlowCardService.class.getName(), flowCardService);
}
}
动态代理:对实现了接口的目标对象FlowCardServiceImpl生成代理对象.
________________________________________________________________________________________
4.简化的工厂3:通过读取配置文件:业务层依赖于Dao接口 drp_my1.7.1
1.Dao层接口
public interface FlowCardDao {
public void addFlowCardMaster(FlowCard flowCard)
}
2.Dao实现:
public class FlowCardDao4MySqlImpl implements FlowCardDao {
public void addFlowCardMaster(FlowCard flowCard){
Connection conn = ConnectionManager.getConnection();
.......
//close pstmt,don't close connection
}
}
3.工厂类:
//public class FlowCardDaoFactory {
//private FlowCardDao flowCardDao;
//
//public FlowCardDaoFactory(FlowCardDao flowCardDao) {
//this.flowCardDao = flowCardDao;
//}
//}
4.业务逻辑接口:
public interface FlowCardService {
public void addFlowCard(FlowCard flowCard);
}
5.业务逻辑实现:
public class FlowCardServiceImpl implements FlowCardService {
private FlowCardDao flowCardDao;
public FlowCardServiceImpl(FlowCardDao flowCardDao) {
this.flowCardDao = flowCardDao;
}
public void addFlowCard(FlowCard flowCard){
//因为依赖于Dao接口,直接调用Dao层的方法
flowCardDao.addFlowCardMaster(flowCard);
}
}
6.读取配置文件: InitServlet
public class InitServlet extends HttpServlet {
public void init() {
String className = props.getProperty("flowCardDao");
FlowCardDao flowCardDao = (FlowCardDao)Class.forName(className).newInstance();
//flowCardDao = (FlowCardDao)new FlowCardDaoFactory(flowCardDao);
FlowCardService flowCardService = new FlowCardServiceImpl(flowCardDao);
this.getServletContext().setAttribute("flowCardService", flowCardService);
}
}
因为业务层实现类依赖于Dao接口,初始化的时候读取出来的是具体的Dao,转换为Dao接口.
直接传给业务层的构造函数.而不必经过传给Dao工厂类这一步.这样把工厂类删掉也行的.
这些想想:工厂的作用是什么,去掉工厂类,工厂创建产品的行为被转换为直接读取出Dao实现类,
转换为Dao接口,传给业务层构造函数.除非业务层依赖的是工厂.而不是Dao.这样工厂就有存在的必要了.
存在工厂,比如用抽象工厂,一个工厂可以创建出多个产品 ,不再是单一系列产品,比如:UserDao,ItemDao.
业务层依赖于工厂,业务的方法通过调用工厂的方法得到createUserDao(),createItemDao()...再调用Dao方法.
动态代理InitServlet的配置:
String className = props.getProperty("flowCardDao");
FlowCardDao flowCardDao = (FlowCardDao)Class.forName(className).newInstance();
//flowCardDao = (FlowCardDao)new FlowCardDaoFactory(flowCardDao);
//FlowCardService flowCardService = new FlowCardServiceImpl(flowCardDao);
TransactionHandler transactionHandler = new TransactionHandler();
FlowCardService flowCardService = (FlowCardService)
transactionHandler.newProxy(new FlowCardServiceImpl(flowCardDao));
this.getServletContext().setAttribute("flowCardService", flowCardService);
_____________________________________________________________________________________________
4.简化的工厂模式4:业务层依赖于工厂,读取配置文件: drp_my1.7.1.2
1.Dao层接口
public interface FlowCardDao {
public void addFlowCardMaster(FlowCard flowCard)
}
2.Dao实现:
public class FlowCardDao4MySqlImpl implements FlowCardDao {
public void addFlowCardMaster(FlowCard flowCard){
Connection conn = ConnectionManager.getConnection();
.......
//close pstmt,don't close connection
}
}
3.工厂类:
public class FlowCardDaoFactory {
private FlowCardDao flowCardDao;
public FlowCardDaoFactory(FlowCardDao flowCardDao) {
this.flowCardDao = flowCardDao;
}
public FlowCardDao createFlowCardDao() {
return flowCardDao;
}
}
4.业务逻辑接口:
public interface FlowCardService {
public void addFlowCard(FlowCard flowCard);
}
5.业务逻辑实现:
public class FlowCardServiceImpl implements FlowCardService {
private FlowCardDaoFactory flowCardDaoFactory;
public FlowCardServiceImpl(FlowCardDaoFactory flowCardDaoFactory) {
this.flowCardDaoFactory = flowCardDaoFactory;
}
public void addFlowCard(FlowCard flowCard){
//因为依赖于工程,通过工厂创建产品 ,再调用到Dao层的方法
flowCardDaoFactory.createFlowCardDao().addFlowCardMaster(flowCard);
}
}
6.读取配置文件: InitServlet
public class InitServlet extends HttpServlet {
public void init() {
String classFlowCardDao = propFlowCard.getProperty("flowCardDao");
FlowCardDao flowCardDao = (FlowCardDao)Class.forName(classFlowCardDao).newInstance();
//把创建好的具体Dao传给工厂类的构造器
FlowCardDaoFactory flowCardDaoFactory = (FlowCardDaoFactory)new FlowCardDaoFactory(flowCardDao);
//业务层依赖于工厂,把工厂传给业务层的构造器
FlowCardService flowCardService = new FlowCardServiceImpl(flowCardDaoFactory);
this.getServletContext().setAttribute("flowCardService", flowCardService);
}
}
把Dao接口传给工厂的构造函数.而不是传给业务层的构造函数.
存在工厂,就是通过业务层访问的是工厂,而不是把Dao接口直接开放给业务层.
业务层调用Dao层的方法必须先通过工厂创建出产品,然后调用Dao层的方法.
动态代理InitServlet的配置: drp_my1.7.1.3:
String className = props.getProperty("flowCardDao");
FlowCardDao flowCardDao = (FlowCardDao)Class.forName(className).newInstance();
FlowCardDaoFactory FlowCardDaoFactory = (FlowCardDao)new FlowCardDaoFactory(flowCardDao);
//FlowCardService flowCardService = new FlowCardServiceImpl(flowCardDaoFactory);
TransactionHandler transactionHandler = new TransactionHandler();
FlowCardService flowCardService = (FlowCardService)
transactionHandler.newProxy(new FlowCardServiceImpl(flowCardDaoFactory));
this.getServletContext().setAttribute("flowCardService", flowCardService);
___________________________________________________________________________________________
总结工厂模式:
1.工厂模式:由工厂的实现类来创建出Dao实现产品,
业务层依赖于工厂接口.调用工厂接口的方法得到Dao接口,调用Dao接口的方法完成与Dao层的交互.
但是需要创建的工厂必须是具体的工厂实现.因为业务层实际上是跟某个具体工厂交互的.(具体的东西了)
只不过通过工厂接口,更通用些,移植更方便.
2.读取配置文件放在构造函数里:
采用单例模式,因为读取配置文件在私有构造函数里,读取出来的就是具体的实现类,转换为工厂接口即可.
3.分离出读取配置文件,业务层抽取出接口:
因为把读取配置文件的操作分离出放在InitServlet里,所以读取出来的是具体的实现类,需要转换为接口,
同时为业务层提供公共的构造函数,传给构造函数.因为业务层需要的工厂接口.
传递给业务层构造函数的只要是工厂的接口就可以,因为是面向接口编程,不需要知道具体的工厂实现类.
ItemManagerImpl的依赖关系是ItemDaoFactory工厂接口.拿到ItemDaoFactory,
调用ItemDaoFactory的方法,返回的是Dao层的接口,再调用Dao层的方法.
ItemManagerImpl需要具体的工厂实现类,才能调用具体的Dao层实现类的方法.
4.简化的工厂模式,没有工厂实现类:
4.1:工厂的方式是单例,没有读取配置文件,业务层依赖于Dao接口,不是依赖于工厂.
工厂类直接来创建产品.因为没有了具体的工厂实现类,就不能把创建好的工厂实现类转换为接口
传给业务逻辑实现类,然后调用Dao层的方法来完成业务逻辑处理.
4.2:通过动态代理管理事务.
4.3:读取配置文件创建具体的Dao,业务层依赖于Dao接口
把创建好具体的Dao传给业务层的构造器,业务层直接调用业务层的Dao方法.
4.4:读取配置文件创建具体的Dao,业务层依赖于工厂:
不同的是需要把具体的Dao传给工厂的构造器,工厂需要有一个创建产品的方法.
业务层调用工厂时先创建出Dao产品,再调用Dao层的方法.
还要注意工厂接口不能被new出来,只有具体的实现才能被new出来.
抽象的东西都是不能new的只有具体的东西才行.
- 工厂模式学习笔记
- 简单工厂模式学习
- 简单工厂模式学习
- 工厂模式学习
- 工厂模式学习
- 工厂模式的学习
- c++工厂模式学习
- 学习简单工厂模式
- 简单工厂模式学习
- 工厂模式学习
- 学习日记-工厂模式
- 工厂模式学习记录
- 抽象工厂模式学习
- 工厂模式学习
- 工厂模式学习
- 简单工厂模式学习
- 工厂模式学习笔记
- 工厂模式学习笔记
- 重复提交、重复刷新、防止后退的问题以及处理方式
- jsp重复提交问题
- 程序偶尔在进程退出的时候崩溃。
- CCIE贬值
- web2.0站长必知
- 工厂模式学习
- 超链接相关用法集
- Hello world.
- Linux文件系统与设备文件系统
- 10.6 放假结束,正式开始进入学习状态
- 【SQL】DBCC
- 大数阶乘
- SQL SERVER用户权限管理命令
- servlet和JSP过滤器Filter(转载)