【设计模式_青春版】创建型|工厂模式

工厂模式(创建型)

简单工厂模式

又叫静态工厂模式

工厂类中的所有方法都是静态的,其一是需要向其中添加参数来返回不同的对象实例,其一是如下举例。

这里模拟汽车工厂生产汽车:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0YdOBqv5-1646576946632)(java_notes.assets/image-20211028224033180-16354320342478.png)]

代码:

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();
    }
}

某种程度上不符合设计原则(开闭原则),但实际使用最多。

有一个演变过程,从最原始的方法 - 静态工厂方法

工厂方法模式

在简单工厂里加一层:

根据设计原则:工厂方法模式

根据实际业务:简单工厂模式(实际使用较多)

简单工厂模式,无论咋样只要增加产品类,就需要修改已有类的!
所以有了工厂方法模式,在不修改已有类的前提下,可以增加产品类。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DwZi6KiB-1646576946634)(java_notes.assets/image-20211028225219992-16354327410699.png)]

还是生产汽车为例
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();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nWXtPaWU-1646576946634)(java_notes.assets/kuangstudy26822559-d626-4b06-afb2-94eff0019b87.png)]

工厂举例

钟意西华小程序-post的生产

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G2vA8Kck-1646576946635)(java_notes.assets/image-20211129215910066-16381943513231.png)]

//帖子的接口
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层处理)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mXWk5KFO-1646576946636)(java_notes.assets/image-20220218140319488-16451642005602.png)]

抽象工厂(创建型)

一 定义

围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂

优缺点

优点:保证始终是同一产品族,适用于只买一个牌子的产品的客户。
缺点:当产品族需要增加一个新的产品,所有的工厂类都要进行修改。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lEJcHqUQ-1646576946636)(java_notes.assets/image-20220218135124929-16451634861641.png)]

  • 产品族:同一工厂所生产的不同等级的产品,相同厂商不同产品。比如:苹果手机,苹果电脑。
  • 产品等级:不同工厂生产的相同类型的产品,不同厂商相同产品。比如:苹果手机,华为手机。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iNfKCc4D-1646576946637)(java_notes.assets/image-20220218140526153-16451643274165.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d7TN8cRk-1646576946637)(java_notes.assets/image-20220218140438279-16451642792404.png)]

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");
    }
}

抽象工厂相当于生产了一个产品族

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qT0x0Lc0-1646576946637)(java_notes.assets/image-20220218143815961-16451662970236.png)]

SqlSessionFactory工厂模式

mybatis 的 SqlSessionFactory工厂模式 是抽象工厂模式

工厂方法模式实现sqlsession

(从别人博客复制的图)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dy1cI8BQ-1646576946638)(java_notes.assets/1102398-20170913132703188-249470338.png)]

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 底层的设计模式。

简单工厂模式的运用(常用)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZOQQLBxm-1646576946638)(java_notes.assets/image-20220218150549295-164516795045310.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bOPUnmpn-1646576946638)(java_notes.assets/image-20220218145315398-16451671962748.png)]

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());
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值