工厂模式(创建型)
简单工厂模式
又叫静态工厂模式
工厂类中的所有方法都是静态的,其一是需要向其中添加参数来返回不同的对象实例,其一是如下举例。
这里模拟汽车工厂生产汽车:
代码:
Car接口
package com.zbz.设计模式.factory.simple;
public interface Car {
void name();
}
奔驰车类与红旗车类:
package com.zbz.设计模式.factory.simple;
public class Bench implements Car {
@Override
public void name() {
System.out.println("奔驰");
}
}
//----------------------------------------------------
package com.zbz.设计模式.factory.simple;
public class HongQi implements Car {
@Override
public void name() {
System.out.println("红旗");
}
}
汽车生产工厂
package com.zbz.设计模式.factory.simple;
public class CarFactory {
//生产汽车
public static Car makeCar(String name){
if(name.equals("红旗"))
return new HongQi();
else if(name.equals("奔驰"))
return new Bench();
else{
return new HongQi();
}
}
//生产汽车2
public static HongQi makeHq(){
return new HongQi();
}
}
消费者
package com.zbz.设计模式.factory.simple;
public class Consumer {
public static void main(String[] args) {
Car hq = CarFactory.makeCar("红旗");
hq.name();
Car hongQi = CarFactory.makeHq();
hongQi.name();
}
}
某种程度上不符合设计原则(开闭原则),但实际使用最多。
有一个演变过程,从最原始的方法 - 静态工厂方法
工厂方法模式
在简单工厂里加一层:
根据设计原则:工厂方法模式
根据实际业务:简单工厂模式(实际使用较多)
简单工厂模式,无论咋样只要增加产品类,就需要修改已有类的!
所以有了工厂方法模式,在不修改已有类的前提下,可以增加产品类。
还是生产汽车为例
Car接口
Bench和HongQi实现Car
上面
CarFactory接口
package com.zbz.设计模式.factory.method;
public interface CarFactory {
Car make();
}
BenchFactory和HqFactory
package com.zbz.设计模式.factory.method;
public class BenchFactory implements CarFactory{
@Override
public Car make() {
return new Bench();
}
}
//--------------------------------------------------------
package com.zbz.设计模式.factory.method;
public class HqFactory implements CarFactory{
@Override
public Car make() {
return new HongQi();
}
}
Consumer
package com.zbz.设计模式.factory.method;
public class Consumer {
public static void main(String[] args) {
Car hq = new HqFactory().make();
hq.name();
}
}
工厂举例
钟意西华小程序-post的生产
//帖子的接口
interface Post{
//帖子类型常量
int TYPE_BBQ=1;
int TYPE_XWQ=2;
int TYPE_XYQ=3;
int TYPE_SWZL=4;
int TYPE_TZSC=5;
int postType();
}
//具体的一个帖子:表白墙
class Bbq implements Post{
//id
private int id;
//userid(Inteher)
private Integer userid;
//content (内容)
private String content;
//ctime 创建时间
private String ctime;
//status 状态(1为可显示,0为异常不可显示(查库时跳过此状态的数据))
private int status;
//version 乐观锁
private int version;
//imgPath 图片的路径(涉及文件上传):
private String imgPath;
//上传到 jar包根目录img路径下 img/userid/时间戳(年月)/帖子id/ ..... .png
//返回时带上前缀 https://xxxx/+img/userid/时间戳(年月)/帖子id/ ..... .png
//多图片 路径以 "|"分割
public int postType(){
return TYPE_BBQ;
}
//对应的方法
public int saveInMondoDb(Bbq bbq){
//......
}
}
//其他的墙同上(除了跳蚤市场 需要添加单价属性外其他应该没有太大区别)
interface Factory{
Post make();//工厂生产
}
class BbqFactory implements Factory{
@Override
public Post make() {
return new Bbq();
}
}
//说明:
//视图层的接口设计:
// restful风格
// 一个接口即可:
// 前缀/posts/postType(一个整数)/userid
//根据postType来使用对应的工厂来 new 实例,并使用实例中的方法
//例如: (使用switch语法):
当postType==1,
Bbq bbq=new BbqFactory().make();
//再使用bbq.set进行赋值
//最后使用bbq的系列方法进行数据处理(由对应的service层处理)
抽象工厂(创建型)
一 定义
围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂
优缺点
优点:保证始终是同一产品族,适用于只买一个牌子的产品的客户。
缺点:当产品族需要增加一个新的产品,所有的工厂类都要进行修改。
- 产品族:同一工厂所生产的不同等级的产品,相同厂商不同产品。比如:苹果手机,苹果电脑。
- 产品等级:不同工厂生产的相同类型的产品,不同厂商相同产品。比如:苹果手机,华为手机。
IProductFactory
package com.zbz.设计模式.abstractFactory;
public interface IProductFactory {
//make phone
IPhoneProduct phoneProduct();
//make router
IRouterProduct routerProduct();
}
HuaweiFactory
package com.zbz.设计模式.abstractFactory;
public class HuaweiFactory implements IProductFactory{
@Override
public IPhoneProduct phoneProduct() {
return new HuaweiPhone();
}
@Override
public IRouterProduct routerProduct() {
return new HuaweiRouter();
}
}
XiaomiFactory
package com.zbz.设计模式.abstractFactory;
public class XiaomiFactory implements IProductFactory{
@Override
public IPhoneProduct phoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouterProduct routerProduct() {
return new XiaomiRouter();
}
}
IPhoneProduct
package com.zbz.设计模式.abstractFactory;
public interface IPhoneProduct {
void open();
void close();
void sendSms();
void callUp();
}
XiaomiPhone
package com.zbz.设计模式.abstractFactory;
public class XiaomiPhone implements IPhoneProduct{
@Override
public void open() {
System.out.println("open - xiaomi");
}
@Override
public void close() {
System.out.println("close - xiaomi");
}
@Override
public void sendSms() {
System.out.println("sendSms - xiaomi");
}
@Override
public void callUp() {
System.out.println("callUp - xiaomi");
}
}
HuaweiPhone
package com.zbz.设计模式.abstractFactory;
public class HuaweiPhone implements IPhoneProduct{
@Override
public void open() {
System.out.println("open - HW");
}
@Override
public void close() {
System.out.println("close - HW");
}
@Override
public void sendSms() {
System.out.println("sendSms - HW");
}
@Override
public void callUp() {
System.out.println("callUp - HW");
}
}
IRouterProduct
package com.zbz.设计模式.abstractFactory;
public interface IRouterProduct {
void open();
void close();
void wifi();
}
XiaomiRouter
package com.zbz.设计模式.abstractFactory;
public class XiaomiRouter implements IRouterProduct{
@Override
public void open() {
System.out.println("open_router - Xiaomi");
}
@Override
public void close() {
System.out.println("close_router - Xiaomi");
}
@Override
public void wifi() {
System.out.println("wifi - Xiaomi");
}
}
HuaweiRouter
package com.zbz.设计模式.abstractFactory;
public class HuaweiRouter implements IRouterProduct{
@Override
public void open() {
System.out.println("open_router - HW");
}
@Override
public void close() {
System.out.println("close_router - HW");
}
@Override
public void wifi() {
System.out.println("wifi - HW");
}
}
抽象工厂相当于生产了一个产品族
SqlSessionFactory工厂模式
mybatis 的 SqlSessionFactory工厂模式 是抽象工厂模式
工厂方法模式实现sqlsession
(从别人博客复制的图)
1.Sqlsession接口
在sqlsession接口中包含了所有可能执行的sql语句。而Defaultsqlsession是他的实现类,实现了其中的方法。
1 public interface SqlSession extends Closeable {
2
3 /**
4 * Retrieve a single row mapped from the statement key
5 * @param <T> the returned object type
6 * @param statement
7 * @return Mapped object
8 */
9 <T> T selectOne(String statement);
10 /**
11 * Retrieve a list of mapped objects from the statement key and parameter.
12 * @param <E> the returned list element type
13 * @param statement Unique identifier matching the statement to use.
14 * @return List of mapped object
15 */
16 <E> List<E> selectList(String statement);
2.DefaultSqlSession
1 public class DefaultSqlSession implements SqlSession {
2
3 private Configuration configuration;
4 private Executor executor;
5
6 private boolean dirty;
7
8 public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
9 try {
10 MappedStatement ms = configuration.getMappedStatement(statement);
11 List<E> result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
12 return result;
13 } catch (Exception e) {
14 throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
15 } finally {
16 ErrorContext.instance().reset();
17 }
18 }
3.SqlSessionFactory接口
sqlsessionfactory类中有opsession方法,用来创建sqlsession。
4、DefaultSqlSessionFactory类
实现了SqlSessionFactory
工厂模式总结
在实际开发中,一般采用简单工厂模式 + 配置文件的形式创建对象,这也是 Spring 底层的设计模式。
简单工厂模式的运用(常用)
calender类为工厂
通过createCalendar方法创建实例
public static Calendar getInstance() {
Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
cal.sharedZone = true;
return cal;
}
private static Calendar createCalendar(TimeZone zone, Locale aLocale) {
Calendar cal = null;
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype == null) {
// Calendar type is not specified.
// If the specified locale is a Thai locale,
// returns a BuddhistCalendar instance.
if ("th".equals(aLocale.getLanguage())
&& ("TH".equals(aLocale.getCountry()))) {
cal = new BuddhistCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
} else if (caltype.equals("japanese")) {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else if (caltype.equals("buddhist")) {
cal = new BuddhistCalendar(zone, aLocale);
} else {
// Unsupported calendar type.
// Use Gregorian calendar as a fallback.
cal = new GregorianCalendar(zone, aLocale);
}
return cal;
}
在java中的calendar
Logback 中,也可以看到 LoggerFactory 中有多个重载的方法 getLogger()。
通过传递不同的参数来创建不同的Logger
public static Logger getLogger(String name){
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
public static Logger getLogger(Class clazz){
return getLogger(clazz.getName());
}
spring-ioc: 简单工厂模式+配置文件
通过配置文件beans.xml中bean标签的id为hello来创建Hello的实例
context就是工厂其中的方法getBean 可以通过参数来创建不同的bean实例
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());