工厂模式的概念、案例、原理

工厂方法案例

1. 类图

在这里插入图片描述

2. 代码

package com.joncy.factoryMethod;

//产品等级,产品族.工厂方法解决前者,抽象工厂解决后者
public abstract class Video {
	public abstract void produce();
}

package com.joncy.factoryMethod;

public class JavaVideo extends Video{

	@Override
	public void produce() {
		System.out.println("生产 JAVA 视频");
	}

}

package com.joncy.factoryMethod;

public class PythonVideo extends Video{

	@Override
	public void produce() {
		System.out.println("生产 Python 视频");
	}
	
}

package com.joncy.factoryMethod;

/**
 * 
 * @author Joncy Zhang
 *	为什么使用抽象类?因为在实际的业务场景,我们的抽象类有可能对于某些行为、属性是已知的。所以
 *      这里面除了抽象方法,还有一些已知的实现。如果里面全是未知的,我们可以用接口来定义
 */
public abstract class VideoFactory {
	public abstract Video getVideo();
}	

package com.joncy.factoryMethod;

public class JavaVideoFactory extends VideoFactory {

	@Override
	public Video getVideo() {
		return new JavaVideo();
	}

}
package com.joncy.factoryMethod;

public class PythonVideoFactory extends VideoFactory{
	@Override
	public Video getVideo() {
		return new PythonVideo();
	}

}
package com.joncy.factoryMethod;

import org.junit.jupiter.api.Test;

public class Application {
	
	@Test
	public void test() {
		VideoFactory videoFactory1 = new JavaVideoFactory();
		Video javaVideo = videoFactory1.getVideo();
		javaVideo.produce();
		VideoFactory videoFactory2 = new PythonVideoFactory();
		Video pythonVideo = videoFactory2.getVideo();
		pythonVideo.produce();
	}
}

运行结果:
在这里插入图片描述

工厂方法概念与原理

1. 定义

  • 定义创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行
  • 类型:创建型

2.适用场景

  • 创建对象需要大量重复代码
  • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
  • 一个类通过其子类来指定创建哪个对象
    不需要知道具体产品的类名,只需要知道生产产品的工厂就可以。有人可能回想,知道工厂类名不就可以倒推出产品的类名?实际不是这样的,我们在案例中知识为了方便理解写成这样而已。

    还记得简单工厂的缺点吗?它的工厂负责的职责太多了,而抽象工厂,将生成产品推给子类,每个子类负责一个产品。

    我们可以总结一下,无论是简单工厂,还是工厂方法,都在做一件事情,那就是封装具体类的生成细节,也就是new对象的过程。

3. 优缺点

  • 优点:用户只需要关心所需产品对应的工厂,无须关心创建细节;加入新产品符合开闭原则,提高可扩展性。
  • 缺点:类的个数容易过多(从案例就知道,在添加产品的时候,不仅要加产品类,还要加产品的工厂类),增加复杂度。增加了系统的抽象性和理解难度
发布了106 篇原创文章 · 获赞 91 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_42512488/article/details/90401637