#yyds干货盘点#设计模式之工厂模式
Posted 汤圆学Java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#设计模式之工厂模式相关的知识,希望对你有一定的参考价值。
作者:汤圆
个人博客:javalover.cc
前言
工厂我们都知道,就是生产东西的地方;
以前的农业时代,我们需要啥东西,都是自己做,比如椅子、桌子;
后来到了工业时代,我们需要啥东西,大部分都是工厂做,你只需要告诉工厂需要的东西。
其实软件中的工厂设计模式,也是类似:不需要我们自己去创建对象,只需要告诉工厂类,需要啥对象,工厂类会帮你创建。
下面我们循序渐进来介绍下工厂模式
目录
- 制作一种椅子
- 制作多种椅子
- 创建一个椅子工厂(简单工厂模式)
- 创建多个椅子工厂(工厂方法模式)
- 创建多个椅子工厂(抽象工厂模式)
正文
1. 制作一种椅子
这个是最简单的了,就是谁需要,谁就创建一个,很方便;
package pattern.factory.nofactory;
/**
* 没有工厂,直接创建椅子
*/
public class NoFactory {
public static void main(String[] args) {
Chair chair = new Chair();
chair.prepare();
chair.make();
chair.box();
}
static class Chair {
public String name = "小椅子";
public void prepare() {
System.out.println(name + "的原材料是:A,B,C");
}
public void make(){
System.out.println(name + "制作中");
}
public void box(){
System.out.println(name + "打包中");
}
}
}
2. 制作多种椅子
过了几天,小李觉得这种椅子不舒服,没有靠背,于是又创建了带靠背的椅子
package pattern.factory.nofactory;
/**
* 没有工厂,直接创建椅子(多种椅子)
*/
public class NoFactory2 {
public static void main(String[] args) {
Chair chair = new ChairA();
chair.prepare();
chair.make();
chair.box();
Chair chairB = new ChairB();
chairB.prepare();
chairB.make();
chairB.box();
}
}
abstract class Chair {
public String name;
public abstract void prepare();
public void make(){
System.out.println(name + "制作中");
}
public void box(){
System.out.println(name + "打包中");
}
}
class ChairA extends Chair {
public ChairA() {
this.name = "小椅子";
}
@Override
public void prepare() {
System.out.println(name + "的原材料是:A,B,C");
}
}
class ChairB extends Chair {
public ChairB() {
this.name = "靠背椅";
}
@Override
public void prepare() {
System.out.println(name + "的原材料是:A2,B2,C2");
}
}
这样看来,好像问题也不大;
可以是如果不止两种,而是十几种几十种呢?
此时再一个个创建就很麻烦了;
于是就有了工厂模式。
3. 创建一个椅子工厂(简单工厂模式)
小李花钱建了一个工厂,专门做各种各样的椅子,这样他每天都可以换不同的椅子坐;
大概的流程就是小李需要什么椅子,就告诉工厂,工厂来做(不再需要自己做)。
package pattern.factory.simple1;
public class SimpleFactory1 {
public static void main(String[] args) {
SimpleChairFactory simpleChairFactory = new SimpleChairFactory();
simpleChairFactory.order("小椅子");
simpleChairFactory.order("靠背椅");
}
}
class SimpleChairFactory {
public Chair chair;
public void order(String name){
if(name == "小椅子"){
chair = new ChairA();
}else if(name == "靠背椅"){
chair = new ChairB();
}else{
chair = null;
}
if(chair != null){
chair.prepare();
chair.make();
chair.box();
}else{
System.out.println("找不到对应的椅子");
}
}
}
abstract class Chair {
public String name;
public abstract void prepare();
public void make(){
System.out.println(name + "制作中");
}
public void box(){
System.out.println(name + "打包中");
}
}
class ChairA extends Chair {
public ChairA() {
this.name = "小椅子";
}
@Override
public void prepare() {
System.out.println(name + "的原材料是:A,B,C");
}
}
class ChairB extends Chair {
public ChairB() {
this.name = "靠背椅";
}
@Override
public void prepare() {
System.out.println(name + "的原材料是:A2,B2,C2");
}
}
上面这个就是简单工厂模式,通过把自己的需求告诉工厂,工厂去做出你想要的东西;
4. 创建多个椅子工厂(工厂方法模式)
上面的简单工厂模式,确实很简单,用起来也很方便;
但是有一个很大的缺点,就是如果需要增加椅子的种类,那么就需要修改工厂类的源代码;
这样一来就违背了开闭原则:对类的扩展开放,对类的修改关闭;
所以我们需要对其进行改进,创建多个工厂子类,来实现不同的创建任务。
package pattern.factory.method;
/**
* 工厂方法模式:将工厂类抽象出来,子类去实现对象的创建
*/
public class MethodFactory {
public static void main(String[] args) {
SmallChairFactory smallFactory = new SmallChairFactory();
smallFactory.order();
BackChairFactory backFactory = new BackChairFactory();
backFactory.order();
}
}
interface ChairFactory{
void order();
}
class SmallChairFactory implements ChairFactory{
public Chair chair;
public void order(){
chair = new ChairA();
chair.prepare();
chair.make();
chair.box();
}
}
class BackChairFactory implements ChairFactory{
public Chair chair;
public void order(){
chair = new ChairB();
chair.prepare();
chair.make();
chair.box();
}
}
abstract class Chair {
public String name;
public abstract void prepare();
public void make(){
System.out.println(name + "制作中");
}
public void box(){
System.out.println(name + "打包中");
}
}
class ChairA extends Chair {
public ChairA() {
this.name = "小椅子";
}
@Override
public void prepare() {
System.out.println(name + "的原材料是:A,B,C");
}
}
class ChairB extends Chair {
public ChairB() {
this.name = "靠背椅";
}
@Override
public void prepare() {
System.out.println(name + "的原材料是:A2,B2,C2");
}
}
5. 创建多个椅子工厂(抽象工厂模式)
上面的工厂方法模式,虽然解决了简单工厂模式的问题(不好扩展,单个类任务繁重),但是它本身也是有缺点的;
就是工厂方法模式中,一个工厂子类只负责生产一种产品,所以后期增加产品时,会导致工厂类过多;
这时就需要将产品进行一个简单的分类(按特定的属性分类,比如按材质分类):比如木头椅子,全都让一个厂去做;塑料椅子,让另一个厂去做。
然后每个材质的椅子,内部再按结构分类(小椅子,靠背椅);
这个就是抽象工厂模式的核心:将产品进行分类,然后分配到不同的工厂子类中。
下面这个例子是先按照材质进行大的分类,再按照结构进行小的分类:
package pattern.factory.abstract1;
/**
* 抽象工厂模式:将工厂类抽象出来,再把产品分类,每个子工厂生产特定类型的产品
*
* 是工厂方法模式的升级版,工厂方法模式是一个工厂只做一个产品,而抽象工厂模式是一个工厂做一类产品
*/
public class AbstractFactory {
public static void main(String[] args) {
// 木头
WoodChairFactory woodChairFactory = new WoodChairFactory();
woodChairFactory.orderSmallChair();
woodChairFactory.orderBackChair();
// 塑料
PlasticChairFactory plasticChairFactory = new PlasticChairFactory();
plasticChairFactory.orderSmallChair();
plasticChairFactory.orderBackChair();
}
}
interface ChairFactory{
void orderSmallChair();
void orderBackChair();
}
// 木头椅子 工厂
class WoodChairFactory implements ChairFactory{
public WoodChair chair;
@Override
public void orderSmallChair() {
chair = new WoodSmallChair();
chair.prepare();
chair.make();
chair.box();
}
@Override
public void orderBackChair() {
chair = new WoodBackChair();
chair.prepare();
chair.make();
chair.box();
}
}
// 塑料椅子 工厂
class PlasticChairFactory implements ChairFactory{
public PlasticChair chair;
@Override
public void orderSmallChair() {
chair = new PlasticSmallChair();
chair.prepare();
chair.make();
chair.box();
}
@Override
public void orderBackChair() {
chair = new PlasticBackChair();
chair.prepare();
chair.make();
chair.box();
}
}
abstract class Chair {
public String type; // 木头/塑料
public String name; // 小椅子/靠背椅
public void prepare(){
System.out.println(type+name + "的制作步骤是:A,B,C");
}
public void make(){
System.out.println(type+name + "制作中");
}
public void box(){
System.out.println(type+name + "打包中");
}
}
// 木头椅
class WoodChair extends Chair {
public WoodChair() {
this.type = "木头-";
}
}
class WoodSmallChair extends WoodChair{
public WoodSmallChair(){
this.name = "小椅子";
}
}
class WoodBackChair extends WoodChair{
public WoodBackChair(){
this.name = "靠背椅";
}
}
// 塑料椅
class PlasticChair extends Chair {
public PlasticChair() {
this.type = "塑料-";
}
}
class PlasticSmallChair extends PlasticChair{
public PlasticSmallChair(){
this.name = "小椅子";
}
}
class PlasticBackChair extends PlasticChair{
public PlasticBackChair(){
this.name = "靠背椅";
}
}
上面的这个抽象工厂模式的例子,虽然现在增加椅子的种类很方便了,只需要扩展一个椅子的子类就可以(比如铁的椅子,只需要创建 IronChair 继承 Chair就可以了);
但是缺点也很明显,细心的朋友可能发现了,就是如果想要增加其他结构的椅子,比如躺椅,那么就需要先改动 椅子工厂接口(增加躺椅的制作过程),再在每个实现工厂类中去实现。
总结
简单工厂模式,简单好用,缺点是不易扩展,违反了开闭原则;
工厂方法模式,可扩展,但是工厂类过多,会导致代码繁重;
抽象工厂模式,可扩展,工厂类也不会很多,但是这里的扩展只是种类层面的扩展,如果是结构层面的还是不易扩展,也会违反开闭原则。
这三种工厂模式都属于创建者型模式。
以上是关于#yyds干货盘点#设计模式之工厂模式的主要内容,如果未能解决你的问题,请参考以下文章