JAVA设计模式--创建型模式--工厂方法模式

工厂方法(Factory Method)模式:

1. 简单工厂模式

  1. 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
  2. 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

1.1.1意图

  1. 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行

1.1.2主要解决

主要解决接口选择的问题。

1.1.3何时使用

我们明确地计划不同条件下创建不同实例时。

1.1.4如何解决

让其子类实现工厂接口,返回的也是一个抽象的产品。

1.1.5关键代码

创建过程在其子类执行。

1.1.6应用实例

  1. 您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
  2. Hibernate 换数据库只需换方言和驱动就可以。

1.1.7优点

  1. 一个调用者想创建一个对象,只要知道其名称就可以了。
  2. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  3. 屏蔽产品的具体实现,调用者只关心产品的接口。

1.1.8缺点

 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,
 在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

1.1.9使用场景

  1. 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
  2. 数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
  3. 设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。

1.1.10注意事项

    作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
    有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要

在这里插入图片描述

1.1.11代码示例(未用工厂模式前)

在这里插入图片描述

package com.xql.designpattern.controller.factory;

/**
 * @author 
 * @date 2022/08/18 08:07
 **/
public class PizzeStore {

    public static void main(String[] args) {
        new OrderPizza("Greek");
        new OrderPizza("Cheese");
        new OrderPizza("1");
    }

}

package com.xql.designpattern.controller.factory;

import java.util.Objects;

/**
 * 订购披萨渠道1
 *
 * @author 
 * @date 2022/08/18 08:04
 **/
public class OrderPizza {

    private String type;

    public OrderPizza(String type) {
        Pizza pizza = null;
        if ("Greek".equals(type)){
            pizza = new GreekPizza();
            pizza.setName("披萨类型1");
        }else if ("Cheese".equals(type)){
            pizza = new CheesePrizza();
            pizza.setName("披萨类型2");
        }
        if (Objects.isNull(pizza)){
            System.out.println("无当前种类");
            return;
        }
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
    }

}

package com.xql.designpattern.controller.factory;

public abstract class Pizza {

    protected String name;

    public abstract void prepare();

    public void bake() {
        System.out.println(name + " baking;");
    }

    public void cut() {
        System.out.println(name + " cutting;");
    }

    public void box() {
        System.out.println(name + " boxing;");
    }

    public void setName(String name) {
        this.name = name;
    }
}
package com.xql.designpattern.controller.factory;

/**
 * 披萨类型2
 *
 * @author 许清磊
 * @date 2022/08/18 08:01
 **/
public class CheesePrizza extends Pizza{
    @Override
    public void prepare() {
        System.out.println("准备披萨类型2的材料");
    }
}

package com.xql.designpattern.controller.factory;

/**
 * 披萨类型1
 *
 * @author 许清磊
 * @date 2022/08/18 08:01
 **/
public class GreekPizza extends Pizza{

    @Override
    public void prepare() {
        System.out.println("准备披萨类型1的材料");
    }

}

在这里插入图片描述
在这里插入图片描述

1.12代码示例(1.简单工厂模式-非静态)

在这里插入图片描述

package com.xql.designpattern.controller.factory;

/**
 * @author
 * @date 2022/08/18 08:07
 **/
public class PizzeStore {

    public static void main(String[] args) {
        new OrderPizza(new SimpleFactory());
        new OrderPizza(new SimpleFactory());
        new OrderPizza(new SimpleFactory());
    }

}

package com.xql.designpattern.controller.factory;

import java.util.Objects;

/**
 * 订购披萨渠道1
 *
 * @author
 * @date 2022/08/18 08:04
 **/
public class OrderPizza {

    private SimpleFactory simpleFactory;

    public OrderPizza(SimpleFactory simpleFactory) {
        setSimpleFactory(simpleFactory);
    }

    public void setSimpleFactory(SimpleFactory simpleFactory) {

        this.simpleFactory = simpleFactory;
        Pizza bean = simpleFactory.getBean("Cheese");
        if (Objects.nonNull(bean)){
            bean.prepare();
            bean.bake();
            bean.cut();
            bean.box();
        }
    }
}

package com.xql.designpattern.controller.factory;
/**
 * 披萨工厂
 *
 * @author 
 * @date 2022/08/18 08:14
 **/
public class SimpleFactory {

    public Pizza getBean(String type){
        Pizza pizza = null;
        if ("Greek".equals(type)){
            pizza = new GreekPizza();
            pizza.setName("披萨类型1");
        }else if ("Cheese".equals(type)){
            pizza = new CheesePrizza();
            pizza.setName("披萨类型2");
        }
        return pizza;
    }



}

1.1.13代码示例(1.简单工厂模式-静态)

package com.xql.designpattern.controller.factory;

/**
 * @author
 * @date 2022/08/18 08:07
 **/
public class PizzeStore {

    public static void main(String[] args) {
        new OrderPizza();
        new OrderPizza();
        new OrderPizza();
    }

}

package com.xql.designpattern.controller.factory;

import java.util.Objects;

/**
 * 订购披萨渠道1
 *
 * @author
 * @date 2022/08/18 08:04
 **/
public class OrderPizza {

    public OrderPizza() {
        setSimpleFactory();
    }

    public  void setSimpleFactory() {
        Pizza bean = SimpleFactory.getBean("Cheese");
        if (Objects.nonNull(bean)){
            bean.prepare();
            bean.bake();
            bean.cut();
            bean.box();
        }
    }
}

package com.xql.designpattern.controller.factory;
/**
 * 披萨工厂
 *
 * @author
 * @date 2022/08/18 08:14
 **/
public class SimpleFactory {

    public static Pizza getBean(String type){
        Pizza pizza = null;
        if ("Greek".equals(type)){
            pizza = new GreekPizza();
            pizza.setName("披萨类型1");
        }else if ("Cheese".equals(type)){
            pizza = new CheesePrizza();
            pizza.setName("披萨类型2");
        }
        return pizza;
    }



}

1.1.4小结

可以发现改善代码后,披萨店铺直接下单,订单去从工厂提货,假如我们现在新增产品,只需要扩展工厂里面的类即可,耦合度也大大降低。

  1. 简单工厂模式是属于创建型模式,是工厂模式的一-种。简单工厂模式是由一个工厂对象决定创建出哪-种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式
  2. 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
  3. 在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.
  4. 一个调用者想创建一个对象,只要知道其名称就可以了。
  5. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  6. 屏蔽产品的具体实现,调用者只关心产品的接口。

2. 工厂方法模式

2.1需要分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2代码实现

package com.xql.designpattern.controller.factory;


public class PizzaStore {

	public static void main(String[] args) {
		String loc = "bj";
		if (loc.equals("bj")) {
			//创建北京口味的各种Pizza
			new BJOrderPizza();
		} else {
			//创建伦敦口味的各种Pizza
			new LDOrderPizza();
		}
		// TODO Auto-generated method stub
	}

}


package com.xql.designpattern.controller.factory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;





public abstract class OrderPizza {

	//定义一个抽象方法,createPizza , 让各个工厂子类自己实现
	abstract Pizza createPizza(String orderType);

	// 构造器
	public OrderPizza() {
		Pizza pizza = null;
		String orderType; // 订购披萨的类型
		do {
			orderType = getType();
			pizza = createPizza(orderType); //抽象方法,由工厂子类完成
			//输出pizza 制作过程
			pizza.prepare();
			pizza.bake();
			pizza.cut();
			pizza.box();

		} while (true);
	}



	// 写一个方法,可以获取客户希望订购的披萨种类
	private String getType() {
		try {
			BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
			System.out.println("input pizza 种类:");
			String str = strin.readLine();
			return str;
		} catch (IOException e) {
			e.printStackTrace();
			return "";
		}
	}

}

package com.xql.designpattern.controller.factory;



public class BJOrderPizza extends OrderPizza {

	
	@Override
	Pizza createPizza(String orderType) {
	
		Pizza pizza = null;
		if(orderType.equals("cheese")) {
			pizza = new BJCheesePizza();
		} else if (orderType.equals("pepper")) {
			pizza = new BJPepperPizza();
		}
		// TODO Auto-generated method stub
		return pizza;
	}

}

package com.xql.designpattern.controller.factory;




public class LDOrderPizza extends OrderPizza {

	
	@Override
	Pizza createPizza(String orderType) {
	
		Pizza pizza = null;
		if(orderType.equals("cheese")) {
			pizza = new LDCheesePizza();
		} else if (orderType.equals("pepper")) {
			pizza = new LDPepperPizza();
		}
		// TODO Auto-generated method stub
		return pizza;
	}

}

package com.xql.designpattern.controller.factory;

public class LDCheesePizza extends Pizza{

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		setName("伦敦的胡椒pizza");
		System.out.println(" 伦敦的胡椒pizza 准备原材料");
	}
}

package com.xql.designpattern.controller.factory;


//将Pizza 类做成抽象
public abstract class Pizza {
	protected String name; //名字

	//准备原材料, 不同的披萨不一样,因此,我们做成抽象方法
	public abstract void prepare();


	public void bake() {
		System.out.println(name + " baking;");
	}

	public void cut() {
		System.out.println(name + " cutting;");
	}

	//打包
	public void box() {
		System.out.println(name + " boxing;");
	}

	public void setName(String name) {
		this.name = name;
	}
}

package com.xql.designpattern.controller.factory;

public class LDPepperPizza extends Pizza{
	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		setName("伦敦的奶酪pizza");
		System.out.println(" 伦敦的奶酪pizza 准备原材料");
	}
}

package com.xql.designpattern.controller.factory;

public class BJCheesePizza extends Pizza {

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		setName("北京的胡椒pizza");
		System.out.println(" 北京的胡椒pizza 准备原材料");
	}

}

package com.xql.designpattern.controller.factory;

public class BJPepperPizza extends Pizza {
	@Override
	public void prepare() {
		setName("北京的奶酪pizza");
		System.out.println(" 北京的奶酪pizza 准备原材料");
	}
}

3.结合源码分析

JDK中的Calendar类中,就使用了简单工厂模式


Calendar calendar = Calendar.getInstance();
Calendar calendar1 = Calendar.getInstance(TimeZone.getDefault());
Calendar calendar2 = Calendar.getInstance(TimeZone.getDefault(), Locale.CANADA);
    public static Calendar getInstance()
    {
        return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }

    if (aLocale.hasExtensions()) {
            String caltype = aLocale.getUnicodeLocaleType("ca");
            if (caltype != null) {
                switch (caltype) {
                case "buddhist":
                cal = new BuddhistCalendar(zone, aLocale);
                    break;
                case "japanese":
                    cal = new JapaneseImperialCalendar(zone, aLocale);
                    break;
                case "gregory":
                    cal = new GregorianCalendar(zone, aLocale);
                    break;
                }
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从入门小白到小黑

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

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

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

打赏作者

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

抵扣说明:

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

余额充值