首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 设计模式系列(4) —— 工厂模式

Java 设计模式系列(4) —— 工厂模式

作者头像
求和小熊猫
发布2021-01-05 12:26:04
2450
发布2021-01-05 12:26:04
举报

工厂方法模式

工厂模式用于实现逻辑的封装,并通过公共的忌口提供对象的实例化服务,在添加新类时只需要做少量的修改。

1. 静态工厂模式(简单工厂模式)

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

静态工厂属于创建者模式,静态工厂模式的实现需要三个角色

  • 简单工厂:负责创建具体产品产品,工厂类的方法可以被外界直接调用
  • 抽象产品:在 Java 中,抽象产品是由抽象类或者接口担任的,用以让具体产品继承或实现
  • 具体产品:在 Java 中,具体产品是工厂类创建的主要对象。
静态工厂的通用写法
在这里插入图片描述
在这里插入图片描述

工厂角色

public class CandyFactory {
	public enum CandyKind{
		FRUITCANDY("fruitCandy"),COLACANDY("COLACANDY");
		private String kind;
		CandyKind(String kind){
			this.kind = kind;
		}
		
		public String getCandyKind() {
			return this.kind;
		}
	}
	
	public Candy createCandy(String kind) {
		if(kind.equals(CandyKind.COLACANDY.getCandyKind()))
			return new ColaCandy();
		if(kind.equals(CandyKind.FRUITCANDY.getCandyKind())) {
			return new FruitCandy();
		}
		return null;
	}

}

抽象产品

public interface Candy {
	public void testCandy();
}

具体产品

  1. FruitCandy
public class FruitCandy implements Candy {

	@Override
	public void testCandy() {
		System.out.println("Test FruitCandy");

	}

}
  1. ColaCandy
package com.stu.edu.part2.Factorypattern.demo2;

public class ColaCandy implements Candy {

	@Override
	public void testCandy() {
		System.out.println("Test ColaCandy");
		
	}

}

上述写法符合了迪米特法则,但是该种写法难以符合开闭原则,一旦有新的产品品种加入,就需要修改工厂类,因此该种写法使用与具体产品类不多,且具体产品种类长时间不改变的情况。

静态工厂与反射的结合

该方案采用一个 HashMap 存储创建的具体产品与 String 之间的映射,使用反射的方式来创建类。这样不仅代码代码更加精简,并且也符合了开闭原则

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

工厂角色

public class CandyFactory {
	private static Map<String,Class> candyMap = new HashMap<>();
	public void registerCandy(String kind,Class candyclass) {
		candyMap.put(kind, candyclass);
	}
	
	
	public Candy createCandy(String kind) {
		Candy candy = null;
		if(candyMap.containsKey(kind)) {
			try {
				candy = (Candy)candyMap.get(kind).newInstance();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
				return candy;
			}			
		}
		return candy;
		
	}

}

抽象产品

public interface Candy {
	public void enjoyCandy();
}

具体产品

  1. redCandy
public class RedCandy implements Candy {
	@Override
	public void enjoyCandy() {
		System.out.println("Enjoy RedCandy");
		
	}
}
  1. WhiteCandy
public class WhiteCandy implements Candy {
	@Override
	public void enjoyCandy() {
		System.out.println("Enjoy WdhiteCandy");
		
	}

}
静态工厂的进一步优化

当然,并非任何时候都适用反射的方式来创建对象,因此我们可以调用类自身的创建方式来实现。我们可以为每一个类创建一个 newInstance 方法,用于返回该类自身的对象。

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

工厂角色

public class CandyFactory {
	
	private static Map<String,Candy> candyMap = new HashMap<String,Candy>();
	
	public void RegisterCandy(String kind,Candy candy) {
		candyMap.put(kind, candy);
	}

	public  Candy createCandy(String kind) {
		if(candyMap.containsKey(kind)) {
			candyMap.get(kind).newInstance();
		}
		return null;
	}

}

抽象产品角色

public interface Candy {
	
	public Candy newInstance();
	public void showCandy();
}

具体产品角色

  1. SoftCandy
public class SoftCandy implements Candy {
	@Override
	public SoftCandy newInstance() {
		// TODO Auto-generated method stub
		return new SoftCandy();
	}
	
	@Override
	public void showCandy() {
		System.out.println("This is a SoftCandy");
	}
	
}
  1. HardCandy
public class HardCandy implements Candy {
	
	@Override
	public HardCandy newInstance() {
		return new HardCandy();
	}
	@Override
	public void showCandy() {
		// TODO Auto-generated method stub
		System.out.println("This is a HardCandy");
	}
}
  1. MilkCandy
public class MilkCandy implements Candy {
	
	@Override
	public MilkCandy newInstance() {
		// TODO Auto-generated method stub
		return new MilkCandy();
	}
	@Override
	public void showCandy() {
		// TODO Auto-generated method stub
		System.out.println("This is a MilkCandy");;
	}
}
简单工厂模式的优缺点

优点:

  • 结构简单,调用方便
  • 共产和产品职责区分明确

缺点:

  • 工厂类单一,负责所有产品的创建,产品基数增多时工厂类会非常臃肿

2. 工厂方法模式

工厂方法模式又称为多态性工厂模式,指定一个创建对象的接口,但由实现这个接口的类来决定实例化哪一个类。

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

在工厂方法模式中,共涉及到4个角色:

  • 抽象工厂角色:定义产品对象的产生
  • 具体工厂角色:实现了抽象共产,负责具体产品的创建
  • 抽象产品角色:定义具体产品的共性
  • 具体产品角色:具体产品的实例
工厂方法模式示例
在这里插入图片描述
在这里插入图片描述

抽象工厂

public abstract class CandyFactory {
	
	public abstract Candy productCandy();
	public List<Candy> orderProduct(int number) {
		List<Candy> candyList = new ArrayList<>();
		int i=0;
		do {
			Candy candy = productCandy();
			candyList.add(candy);
			i++;
		}while(i<number);
		return candyList;
	}
}

具体工厂

  1. HardCandyFactory
public class HardCandyFactory extends CandyFactory {

	@Override
	public Candy productCandy() {
		return new HardCandy();
	}

}
  1. SoftCandyFactory
public class SoftCandyFactory extends CandyFactory {

	@Override
	public Candy productCandy() {
		return new OrangeSoftCandy();
	}

}

抽象产品

public interface Candy {
	
	public void enjoyCandy();

}

具体产品

1.SoftCandy

public class OrangeSoftCandy implements Candy {

	@Override
	public void enjoyCandy() {
		System.out.println("Enjoy Orange SoftCandy");
	}

}
  1. OrangeHardCandy
public class HardCandy implements Candy {

	@Override
	public void enjoyCandy() {
		System.out.println("Enjoy Orange HardCandy");

	}

}
工厂方法模式的优缺点

优点:

  • 良好的封装性
  • 优秀的可扩展性,灵活性,对于新产品或者产品类的创建,只需多写一个相应的工厂类,而无需修改工厂类,调用时也不会
  • 屏蔽产品类,产品类如何实现变化无需调用者都不用关心,只需关注接口即可

缺点:

  • 类产品过多,会增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品

3. 抽象工厂模式

抽象工厂指提供一个创建一系列相关或相互依赖对象的接口,无需指定他们具体的类。意思是,客户端不必指定产品的具体类型,创建多个产品族中的具体对象。

抽象工厂和工厂方法一样拥有四个对象:

  • 抽象工厂:声明创建抽象产品对象的一个操作接口
  • 具体工厂:实现创建具体产品对象的操作
  • 抽象产品:为一类产品对象声明一个接口
  • 具体产品:定义一个将被相应的具体工厂的创建的产品对象,是实现 AbstractProduct 接口
在这里插入图片描述
在这里插入图片描述

上图为 抽象工厂模式的一个 UML 图

我们可以借助下图帮助我们理解一下

在这里插入图片描述
在这里插入图片描述
抽象工厂模式示例

抽象工厂

public interface CandyFactory {
	public HardCandy createHardCandy();
	public SoftCandy createSoftCandy();

}

具体工厂

  1. AppleFlavorCandyFactory
public class AppleFlavorCandyFactory implements CandyFactory {

	@Override
	public HardCandy createHardCandy() {
		return new AppleHardCandy();
	}

	@Override
	public SoftCandy createSoftCandy() {
		return new AppleSoftCandy();
	}

}
  1. OrangeFlavorCandyFactory
public class OrangeFlavorCandyFactory implements CandyFactory {

	@Override
	public HardCandy createHardCandy() {
		return new OrangeHardCandy();
	}

	@Override
	public SoftCandy createSoftCandy() {
		return new OrangeSoftCandy();
	}

}

抽象产品

  1. SoftCandy
public interface SoftCandy {
	public void tasteSoftCandy();
}
  1. HardCandy
public interface HardCandy {
	public void tasteHardCandy();
}

具体产品 1.AppleHardCandy

public class AppleHardCandy implements HardCandy {

	@Override
	public void tasteHardCandy() {
		System.out.println("The Apple Hard Candy taste delicious");
	}

}
  1. AppleSoftCandy
public class AppleSoftCandy implements SoftCandy {

	@Override
	public void tasteSoftCandy() {
		System.out.println("The Apple Soft Candy taste delicious");
	}
    
}
  1. OrangeHardCandy
public class OrangeHardCandy implements HardCandy {

	@Override
	public void tasteHardCandy() {
		System.out.println("The Orange Hard Candy taste delicious");		
	}

}
  1. OrangeSoftCandy
public class OrangeSoftCandy implements SoftCandy {

	@Override
	public void tasteSoftCandy() {
		System.out.println("The Orange Soft Candy taste delicious");
	}

}
抽象工厂模式的优缺点

优点:

  1. 当需要产品族时,抽象共产可以保证客户端始终只使用一个产品的产品族
  2. 抽象工厂增强了程序的可扩展性,对于新产品族的增加,秩序实现一个新的具体工厂即可

缺点:

  1. 规定了所有可能被创建的产品的集合,产品族中添加新的扩展会更加困难
  2. 增加了系统的抽象性和理解难度
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-12-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 工厂方法模式
    • 1. 静态工厂模式(简单工厂模式)
      • 2. 工厂方法模式
        • 3. 抽象工厂模式
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档