设计模式-简单工厂

为什么使用工厂模式?

        1、new对象的细节我不想关心,我只想使用该对象。
        2、当一个对象的构造方法需要多个以上的参数的时候,这个就比较麻烦了。
        3、当一个对象是第三方jar包提供的,在构建该对象时,我不知道应该传哪些构造参数或者搞明白这些构造参数很费劲,比如说BasicDataSource类
                
使用工厂模式创建的对象要不是就是一大堆(每个都不同),要不就是一大批(每个都相同)
工厂生产的一般不是数据对象,都是业务对象  (Student---数据对象  UserService---业务对象)

优缺点
优点:
很明显,简单工厂的特点就是“简单粗暴”,通过一个含参的工厂方法,我们可以实例化任何产品类,上至飞机火箭,下至土豆面条,无所不能。所以简单工厂有一个别名:上帝类。
缺点:
任何”东西“的子类都可以被生产,负担太重。当所要生产产品种类非常多时,工厂方法的代码量可能会很庞大。
在遵循开闭原则(对拓展开放,对修改关闭)的条件下,简单工厂对于增加新的产品,无能为力。因为增加新产品只能通过修改工厂方法来实现。

工厂方法正好可以解决简单工厂的这两个缺点。

spring中是通过配置文件和反射解决了简单工厂中的缺点。


工厂设计模式相关概念:

1、产品:类

2、抽象产品:抽象类,接口

3、产品簇

4、产品等级

 

 

学习设计模式,脑袋里要时刻蹦两根弦:

       A:开发代码的程序猿,被划分为两种角色

              作者(服务器端程序猿)

              用户(客户端程序猿)

              比如,我们使用C3p0时,我们拿着别人写好的数据库连接池的字节码在使用,制作c3p0的程序猿就是作者。

       B:我们手头并不会是时刻都拥有作者的源代码的,比如在使用c3p0时,我们能用,但是我们找不到c3p0的源码文件(*.Java),此时就算我们想篡改c3p0的源代码,都找不着。就算我们有c3p0的源代码,也不能改,因为要符合开闭原则。

简单工厂示例

package com.wang.h_simplefactory.a;
//抽象产品
interface Food{
	void eat();
}
//具体产品
class Hamburger implements Food{
	public void eat() {
		System.out.println("吃汉堡包");
	}
}

// ===============================================================
public class AppTest {
	public static void main(String[] args) {
		Food f= new Hamburger();
		f.eat();
    }
}

缺点:这种设计相当脆弱: 为什么?因为,只要作者修改了具体产品的类名,那么客户端代码,也要随之一起修改。
这样服务器代码和客户端代码就是耦合的。

我们希望的效果是,无论服务器代码如何修改,客户端代码都应该不知道,不用修改客户端代码
 

package com.wang.h_simplefactory.b;

// 针对a包中的问题,服务器代码一旦修改,客户端代码也要跟着修改。
// 作者修改代码如下:使用简单工厂设计模式。
//抽象产品
interface Food {
	void eat();
}

// 具体产品
class Hamburger implements Food {
	public void eat() {
		System.out.println("吃汉堡包");
	}
}
class RiceNoodle implements Food {
	public void eat() {
		System.out.println("吃过桥米线");
	}
}
class FoodFactory {
	public static Food getFood(int n) {
		Food food = null;
		switch (n) {
		case 1:
			food = new Hamburger();
			break;
		case 2:
			food = new RiceNoodle();
			break;
		default:
			break;
		}
		return food;
	}
}

// ===============================================================
class LP  implements Food{
	public void eat() {
		System.out.println("三秦套餐 - 吃凉皮");
	}
}
public class AppTest {
	public static void main(String[] args) {
		Food f = FoodFactory.getFood(1);
		f.eat();
	}
}
/**
 * 接口要趋向于稳定,
 * 设计模式中的接口,不单指interface,只要是下层给上层暴露的方法,都叫接口。一个公共方法,或者类,只要暴露出去,都是接口。
 * 简单工厂
 * 优点:
 * 1、把具体产品的类型,从客户端解耦出来
 * 2、服务器端,如果修改了具体产品的类名,客户端也不知道,这符合了面向接口编程思想。
 * 
 * 缺点:
 * 1、客户端必须自己去记具体常量与产品之间的映射关系。
 * 2、如果具体产品特别多,则简单工厂,就会变得十分臃肿。比如100个产品,则switch中就有100个case。
 * 3、最重要的是,变化来了,客户端需要扩展新的产品。则用户势必要修改简单工厂的代码,这样便违反的开闭原则。
 */

 

简单工厂UML例图

知识备注:

c3p0是什么?

c3p0是一个库,c3p0.jar。它扩展了传统的jdbc数据库连接池,并且支持JDBC3规范和JDBC2的标准扩展。

      c3p0是一种jdbc数据库连接池。

      那么为什么使用数据库连接池呢?

      因为数据库连接是一种关键的、有限的、昂贵的资源。

传统的模式(如传统的java web项目中,servlet的beans中建立数据库连接),每次连接都需要验证用户,消耗了大量的时间和资源。而数据库连接池在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已经建立的空闲连接对象。使用完毕后,用户不关闭连接,而是将数据库连接对象放回连接池中。数据库连接池管理数据连接的建立、断开,同时监视数据库连接数量和使用情况。使用数据库连接池会显著提高整个应用程序的伸缩性(大大提高了连接数量)和健壮性(能够应对大量用户频繁连接数据库,减少系统资源的消耗),提高应用程序的性能指标。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仰望星空@脚踏实地

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值