「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」
介绍:
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
优点:
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
简单工厂模式
基本介绍
1)简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类
的实例。简单工厂模式是工厂模式家族中最简单实用的模式
2)简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
3)在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.
传统建造披萨的方式:
package com.jxau.simplefactory.pizzastore.order;
import com.jxau.simplefactory.pizzastore.pizza.CherresPizza;
import com.jxau.simplefactory.pizzastore.pizza.PepperPizza;
import com.jxau.simplefactory.pizzastore.pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza {
private Pizza pizza;
public OrderPizza(){
do{
String type=gettype();
if("芝士".equals(type)){
pizza=new CherresPizza();
pizza.setName("芝士");
}else if("胡椒".equals(type)){
pizza=new PepperPizza();
pizza.setName("胡椒");
}else{
break;
}
pizza.prepare();
pizza.cut();
pizza.back();
}while (true);
}
public String gettype() {
String type= null;
try {
BufferedReader strign=new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入你想订购的披萨:");
type = strign.readLine();
return type;
} catch (IOException e) {
e.printStackTrace();
return " ";
}
}
}
传统的方式的优缺点 1)优点是比较好理解,简单易操作。
2)缺点是违反了设计模式的ocp原则,即对==扩展开放,对修改关闭==。即当我们给类增加新功能的时候,尽量不修
改代码,或者尽可能少修改代码.
3)比如我们这时要新增加一个Pizza的种类(Pepper 披萨),我们需要做出繁琐的修改
改进的思路分析
分析:修改代码可以接受,但是如果我们在其它的地方也有创建Pizza的代码,就意味着,也需要修改,而创建Pizza的代码,往往有多处。
思路:把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类时,只需要修改该类就可,其它有创建到Pizza
对象的代码就不需要修改了->简单工厂模式
package com.jxau.simplefactory.pizzastore.order;
import com.jxau.simplefactory.pizzastore.pizza.CherresPizza;
import com.jxau.simplefactory.pizzastore.pizza.PepperPizza;
import com.jxau.simplefactory.pizzastore.pizza.Pizza;
public class SimplePizzaFactory {
private Pizza pizza=null;
public Pizza doPizza(String type) {
if ("芝士".equals(type)) {
pizza = new CherresPizza();
pizza.setName("芝士");
} else if ("胡椒".equals(type)) {
pizza = new PepperPizza();
pizza.setName("胡椒");
} else {
return null;
}
pizza.prepare();
pizza.cut();
pizza.back();
return pizza;
}
}
public class OrderPizzaTest02 {
private SimplePizzaFactory simplePizzaFactory;
private Pizza pizza;
public void setSimplePizzaFactory(SimplePizzaFactory simplePizzaFactory) {
this.simplePizzaFactory = simplePizzaFactory;
do{
String type=gettype();
pizza=simplePizzaFactory.doPizza(type);
if(pizza!=null) System.out.println("你的"+pizza.getName()+"已经完成!");
else {System.out.println("暂无此披萨销售!");break;}
}while (true);
}
public OrderPizzaTest02(SimplePizzaFactory simplePizzaFactory){
setSimplePizzaFactory(simplePizzaFactory);
}
}
工厂方法模式:
工厂枋法模式介绍
定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
工厂方法模式设计方案:
将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。
umi类图:
public abstract class OrderPizza {
public OrderPizza(){
Pizza pizza=null;
do{
String type=gettype(); // 订购披萨的类型
pizza=getPizza(type);// 抽象方法,由工厂子类完成
if(pizza==null){
System.out.println("暂无你需要订购的类型");
break;
}else{
pizza.prepare();
pizza.back();
pizza.cut();
}
}while (true);
}
public abstract Pizza getPizza(String type);
}
public class BjOrderPizza extends OrderPizza {
private Pizza pizza=null;
@Override
public Pizza getPizza(String type) {
if("芝士".equals(type)){
pizza=new LondCheresPizza();
pizza.setName("北京芝士");
}else if("胡椒".equals(type)){
pizza=new LondPepperPizza();
pizza.setName("北京胡椒");
}else{
return null;
}
return pizza;
}
}
抽象工厂模式:
基本介绍 1)抽象工厂模式:定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类
2)抽象工厂模式可以将==简单工厂模式==和==工厂方法模式==进行整合。
3)从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
4)将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工
厂子类。
umi类图
相比于之前的工厂方法模式,这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
public interface AbsPizzaFactory {
public Pizza cretatePizza(String type);
}
public class BjFactory implements AbsPizzaFactory {
Pizza pizza=null;
@Override
public Pizza cretatePizza(String type) {
if("芝士".equals(type)){
pizza=new BjCheresPizza();
}else if("胡椒".equals(type)){
pizza=new BjPepperPizza();
}else {
return null;
}
return pizza;
}
}
public class OrderPizza {
private AbsPizzaFactory absPizzaFactory;
private Pizza pizza=null;
public OrderPizza(AbsPizzaFactory absPizzaFactory) {
setAbsPizzaFactory(absPizzaFactory);
}
private void setAbsPizzaFactory(AbsPizzaFactory absPizzaFactory){
this.absPizzaFactory=absPizzaFactory;
do {
String type=gettype();
pizza = absPizzaFactory.cretatePizza(type);
if(pizza!=null){
pizza.prepare();
pizza.back();
pizza.cut();
System.out.println("你订购的披萨已出炉!");
}else{
System.out.println("暂无此类披萨销售!");
break;
}
}while (true);
}
工厂模式在JDK源码中的应用:
Calendar.getInstance();// 日期类静态方法获取一个实例
public static Calendar getInstance()
{
Locale aLocale = Locale.getDefault(Locale.Category.FORMAT);
return createCalendar(defaultTimeZone(aLocale), aLocale);
}
// 使用简单工厂模式
public static Locale getDefault(Locale.Category category) {
// do not synchronize this method - see 4071298
switch (category) {// 根据传入的类型返回对应的Locale对象实例
case DISPLAY:
if (defaultDisplayLocale == null) {
synchronized(Locale.class) {
if (defaultDisplayLocale == null) {
defaultDisplayLocale = initDefault(category);
}
}
}
return defaultDisplayLocale;
case FORMAT:
if (defaultFormatLocale == null) {
synchronized(Locale.class) {
if (defaultFormatLocale == null) {
defaultFormatLocale = initDefault(category);
}
}
}
return defaultFormatLocale;
default:
assert false: "Unknown Category";
}
return getDefault();
}
小结:
工厂模式的意义
1)将实例化对象的代码提取出来,放到==一个类中统一管理和维护==,达到和主项目的依赖关系的解耦。从而提高项
目的扩展和维护性。
2)三种工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)
3)设计模式的依赖抽象原则
-
创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。
-
不要让类继承具体类,而是继承抽象类或者是实现interface(接口)
-
不要覆盖基类中已经实现的方法。