工厂模式
简单工厂模式
工厂方法模式
抽象工厂模式
1.简单工厂模式
1.基本介绍
1)简单工厂模式也叫静态工厂模式,是属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建哪一种产品类的实例。简单工厂模式是工厂模式种最简单实用的模式。
2)简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为
3)在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.
2.解决的问题
将"类实例化的操作"与''使用对象的操作"分开,让使用者不需要知道具体参数就可以实例化出所需要的''产品''类,从而避免了在客户段种显示指定,实现了解耦,即使用者可以直接消费产品而不需要知道其生产的细节。
3.模式的组成
抽象产品(Product):描述产品的公共接口,是具体产品的父类。
具体产品(ConcreteProduct):描述生产的具体产品,抽象产品的子类,工厂类创建的目标类。
工厂(Factory):根据传入不同的参数从而创建不同具体产品类的实例,被外界调用。
4.使用步骤
- 创建抽象产品类&定义具体产品的公共接口;
- 创建具体产品类(继承抽象产品类),定义生产的具体产品;
- 创建工厂类,通过创建静态方法更具传入不同参数从而创建不同具体产品类的实例。
- 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例。
5.优点
- 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦。
- 把初始化实列时的工作放到工厂里进行,是代码更容易维护。更符合面向对象的原则。
5.缺点
- 工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响。
- 违背”开发封闭原则“,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
- 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
6.示例
目的:奶茶店有三种奶茶原味,珍珠和红豆,老板希望使用简单工厂模式生产这>三种奶茶。
代码:
public class SampleFactoryPattern {
public static void main(String[] args) {
Factor.makeProduct("红豆").make();;
Factor.makeProduct("珍珠").make();;
Factor.makeProduct("原味").make();;
}
}
//1.创建抽象产品类,定义具体用户点单的公共接口
interface Product{
public void make();
}
//2.创建具体产品类(实现接口),定义生产的具体产品
class ProductPlain implements Product{
//原味奶茶
@Override
public void make() {
System.out.println("生产了原味奶茶");
}
}
class ProductPearl implements Product{
//珍珠奶茶
@Override
public void make() {
System.out.println("生产了珍珠奶茶");
}
}
class ProductRedBeans implements Product{
//红豆奶茶
@Override
public void make() {
System.out.println("生产了红豆奶茶");
}
}
//3.创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例。
class Factor{
public static Product makeProduct(String name) {
switch(name) {
case "原味":
return new ProductPlain();
case "珍珠":
return new ProductPearl();
case "红豆":
return new ProductRedBeans();
default:
return null;
}
}
}
截图:
2.工厂方法模式
1.基本介绍
工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
2.主要作用
将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)种完成,即由子类决定应用实例(创建)哪一个类。
3.解决的问题
简单工厂模式的缺点,工厂一旦创建需要生产新产品就需要修改工厂类的方法逻辑,违背了"开放封闭原则"。
之所以可以解决简单工厂的问题,是因为工厂方法模式把具体产品的创建推出到工厂类的子类(具体工厂)中,此时工厂类不再负责所有产品的创建,而是给出具体工厂必须实现的接口,这样工厂方法模式再添加新产品的时候就不修改工厂类逻辑而是添加新的工厂子类,符合开放封闭原则,克服了简单工厂模式中的缺点。
4.模式的组成
抽象产品(Product):描述产品的公共接口,是具体产品的父类。
具体产品(ConcreteProduct):描述生产的具体产品,抽象产品的子类,工厂类创建的目标类,描述的具体产品。
抽象工厂(Factory):描述具体工厂的公共接口,具体工厂的父类。
具体工厂(ConcreteCreator):实现FactoryMethod工厂方法创建产品的实例,抽象工厂的子类,被外界调用。
5.使用步骤
1.创建抽象工厂类,定义具体工厂的公共接口;
2.创建抽象产品类,定义具体产品的公共接口
3.创建具体产品类(继承抽象产品类或者实现接口),定义生产的具体产品;
4.创建具体工厂类(继承抽象工厂类或者实现接口),定义创建对应具体产品实例的方法。
5.外界通过调用具体工厂类的放,从而创建不同具体产品类的实例。
6.优点
更符合开放封闭原则,新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可,无需修改。
符合单一职责原则,每个具体工厂类只负责创建对应的产品。
不使用静态工厂方法,可以形成基本继承的等级结构。
工厂模式可以说时简单工厂模式的进一步抽象和拓展,在保留了简单工厂封装的优点的同时,让扩展变得更加简单,让继承变得可行,增加了多态性得体现。
7.缺点
添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
·由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
·虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;
·一个具体工厂只能创建一种具体产品
8.示例
有一间工厂(仅生产A类产品),随着客户需求的变化,可户需要生产B类产品。
·冲突:改变原有塑料加工厂的配置和变化非常困难,假设下一次客户需要再发生变化,再次改变将增大非常大的成本;
·解决方案:小成决定置办塑料分厂B来生产B类产品;
代码:
public class MethodFactory {
public static void main(String[] args) {
FactoryA factoryA=new FactoryA();
factoryA.manufacture().make();
FactoryB factoryB=new FactoryB();
factoryB.manufacture().make();
}
}
//1.创建抽象工厂类,定义具体工厂的公共接口;
abstract class AbstractFactory{
public abstract Product manufacture();
}
//2.创建抽象产品类,定义具体产品的公共接口
abstract class Product{
public abstract void make();
}
//3.创建具体产品类(继承抽象产品类或者实现接口)&定义生产的具体产品;
class ProductA extends Product{
//具体产品A类
@Override
public void make() {
System.out.println("生产了A类产品");
}
}
class ProductB extends Product{
//具体产品B类
@Override
public void make() {
System.out.println("生产了B类产品");
}
}
//4.创建具体工厂类(继承抽象工厂类或者实现接口),定义创建对应具体产品实例的方法。
class FactoryA extends AbstractFactory{
//A工厂
@Override
public Product manufacture() {
return new ProductA();
}
}
class FactoryB extends AbstractFactory{
//B工厂
@Override
public Product manufacture() {
return new ProductB();
}
}
结果:
3.抽象工厂模式
1.基本介绍
1)抽象工厂模式:定义了一个 interface 用于创建相关或有依赖关系的对象簇,而无需指明具体的类
2)抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
3)从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
4)将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
4)工厂方法模式中一个具体工厂只能创建一类产品,而实际过程中,一个工厂往往需要生产多类产品。为解决这类问题,引入抽象工厂模式。
2.主要作用
允许使用抽象得接口来创建一组相关产品,而不需要知道或关心实际生产出得具体产品是什么,这样就可以从具体产品中被解耦。
3.解决得问题
工厂方法模式得缺点
4.模式的组成
抽象产品簇(AbastractProduct):描述抽象产品得公共接口,抽象产品得父类
抽象产品(Product):描述产品的公共接口,是具体产品的父类。
具体产品(ConcreteProduct):描述生产的具体产品,抽象产品的子类,工厂类创建的目标类,描述的具体产品。
抽象工厂(Factory):描述具体工厂的公共接口,具体工厂的父类。
具体工厂(ConcreteCreator):实现FactoryMethod工厂方法创建产品的实例,抽象工厂的子类,被外界调用。
5.使用步骤
1.创建抽象工厂类,定义具体工厂的公共接口;
2.创建抽象产品簇类,定义抽象产品的公共接口;
3.创建抽象产品类(继承抽象产品簇类或者实现接口),定义具体产品的公共接口;
4.创建具体产品类(继承抽象产品类或者实现接口),定义生产的具体产品。
5.创建具体工厂类(继承抽象工厂类或者接口),定义创建对应具体产品实例的方法。
6.客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例。
6.优点
降低耦合:抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度降低,这样更有利于后期的维护和扩展。
跟符合开放闭合原则:新增一种产品类时,只需要增加相应的具体产品代码和相应的工厂子类即可。
符合单一职责原则:每个具体工厂类只负责创建对应的产品
不使用静态工厂方法,可以形成基于继续的等级结构。
7.缺点
抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了开放封闭原则。
8.示例
·背景:小成有两间塑料加工厂(A厂仅生产容器类产品;B厂仅生产模具类产品);随着客户需求的变化,A厂所在地的客户需要也模具类产品,B厂所在地的客户也需要容器类产品;
冲突:没有资源(资金+租位)在当地分别开设多一家注塑分厂
解决方案:在原有的两家塑料厂里增设生产需求的功能,即A厂能生产容器+模具产品;B厂间能生产模具+容器产品。
代码:
public class AbstractFactory {
public static void main(String[] args) {
//A厂
FactoryA fA=new FactoryA();
fA.manufactureContainer().make();
fA.manufactureMould().make();
//B厂
FactoryB fB=new FactoryB();
fB.manufactureContainer().make();
fB.manufactureMould().make();
}
}
//1.创建抽象工厂类,定义具体工厂的公共接口;
abstract class Factory{
public abstract AbstractProduct manufactureContainer();
public abstract AbstractProduct manufactureMould();
}
//2.创建抽象产品簇类,定义抽象产品的公共接口;
abstract class AbstractProduct{
public abstract void make();
}
//3.创建抽象产品类(继承抽象产品簇类或者实现接口),定义具体产品的公共接口;
abstract class ContainerProduct extends AbstractProduct{
//容器抽象类
public abstract void make();
}
abstract class MouldProduct extends AbstractProduct{
//模具抽象类
public abstract void make();
}
//4.创建具体产品类(继承抽象产品类或者实现接口),定义生产的具体产品。
class ContainerProductA extends ContainerProduct{
//容器产品A类
@Override
public void make() {
System.out.println("生产出了容器产品A类");
}
}
class ContainerProductB extends ContainerProduct{
//容器产品B类
@Override
public void make() {
System.out.println("生产出了容器产品B类");
}
}
class MouldProductA extends MouldProduct{
//模具产品A类
@Override
public void make() {
System.out.println("生产出了模具产品A类");
}
}
class MouldProductB extends MouldProduct{
//模具产品B类
@Override
public void make() {
System.out.println("生产出了模具产品B类");
}
}
//5.创建具体工厂类(继承抽象工厂类或者接口),定义创建对应具体产品实例的方法。
class FactoryA extends Factory{
//工厂A,生产模具和容器
@Override
public AbstractProduct manufactureContainer() {
return new ContainerProductA();
}
@Override
public AbstractProduct manufactureMould() {
return new MouldProductA();
}
}
class FactoryB extends Factory{
//工厂B,生产模具和容器
@Override
public AbstractProduct manufactureContainer() {
return new ContainerProductB();
}
@Override
public AbstractProduct manufactureMould() {
return new MouldProductB();
}
}
截图:
emmmm 当看到大佬的博客的时候,为了以后复习和加深记忆,不知不觉又当上了博客搬运工,如果想看原文参考下方链接。