设计模式之抽象工厂模式

本文介绍了抽象工厂模式,包括其原理、特点和适用场景。抽象工厂模式提供了一个创建一系列相关对象的接口,使得客户端无需指定具体类就能得到所需的产品。这种模式符合依赖倒置原则,允许在不修改客户端代码的情况下增加新产品。然而,它也存在一定的复杂性,当添加新产品或新工厂时,需要修改多处代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 引子

上篇讲到,为了实现类的“开闭原则”和“单一职责原则”,把简单工厂模式改为工厂方法模式。通过工厂方法模式,客户只需要从对应的工厂拿到想要的衣服,从短袖工厂拿到短袖,毛衣工厂拿到毛衣,衬衣工厂拿到衬衣;但是,我们除了上衣外,还需要裤子;在这里客户需要按照不同的季节来拿衣服(包括上衣和裤子)。面向对象的抽象过程就是:①抽象工厂接口IFactory,可以生产上衣和裤子;②实体工厂类SpringFactory/SummerFactory/WinterFactory,这里按照季节来分工厂类别,每个季节的工厂生产对应季节的上衣和裤子,SpringFactory生产衬衣Shirt类和长裤Trousers类,SummerFactory生产短袖Cotta类和短裤Shorts类,WinterFactory生产毛衣Sweater类和棉裤Padd类;③抽象上衣类Clothes,抽象裤子类Pants;④实体衣服类,包括短袖Cotta,短裤Shorts,衬衣Shirt,长裤Trousers,毛衣Sweater,棉裤Padd类等;⑤客户端Client类。
① 抽象工厂IFactory:

public interface IFactory {
	Clothes makeClothes(int num);   // 生产上衣
	Pants makePants(int num);       // 生产裤子
}

② 实体工厂类:
SpringFactory:

public class SpringFactory implements IFactory {

	@Override
	public Clothes makeClothes(int num) {
		return new Shirt(num);   // 生产衬衣
	}

	@Override
	public Pants makePants(int num) {
		return new Trousers(num);  // 生产长裤
	}
}

SummerFactory:

public class SummerFactory implements IFactory {

	@Override
	public Clothes makeClothes(int num) {
		return new Cotta(num);  // 生产短袖
	}

	@Override
	public Pants makePants(int num) {
		return new Shorts(num);  // 生产短裤
	}
}

WinterFactory:

public class WinterFactory implements IFactory {

	@Override
	public Clothes makeClothes(int num) {
		return new Sweater(num);   // 生产毛衣
	}

	@Override
	public Pants makePants(int num) {
		return new Padd(num);    // 生产棉裤
	}
}

③ 抽象上衣类Clothes

public abstract class Clothes {}

抽象裤子类Pants

public abstract class Pants {}

④ 实体衣服类
衬衣类Shirt:

public class Shirt extends Clothes {
	public Shirt(int num){
		System.out.println("通过spring工厂制作"+ num +"件衬衫");
	}
}
短袖类Cotta:
public class Cotta extends Clothes {
	public Cotta(int num){
		System.out.println("通过summer工厂制作"+ num +"件短袖");
	}
}

毛衣类Sweater:

public class Sweater extends Clothes {
	public Sweater(int num){
		System.out.println("通过winter工厂制作"+ num +"件毛衣");
	}
}

长裤类Trousers:

public class Trousers extends Pants {
	public Trousers(int num){
		System.out.println("通过spring工厂制作"+ num +"件长裤");
	}
}

短裤类Shorts:

public class Shorts extends Pants {
	public Shorts(int num){
		System.out.println("通过summer工厂制作"+ num +"件短裤");
	}
}

棉裤类Padd:

public class Padd extends Pants {
	public Padd(int num){
		System.out.println("通过winter工厂制作"+ num +"件棉裤");
	}
}

⑤ 客户端类

public class Client {
	public static void main(String[] args) {
		IFactory springFactory = new SpringFactory();
		springFactory.makeClothes(2);
		springFactory.makePants(2);
		System.out.println("=========================");
		IFactory summerFactory = new SummerFactory();
		summerFactory.makeClothes(3);
		summerFactory.makePants(3);
		System.out.println("=========================");
		IFactory winterFactory = new WinterFactory();
		winterFactory.makeClothes(4);
		winterFactory.makePants(4);
	}
}

运算结果:

通过spring工厂制作2件衬衫
通过spring工厂制作2件长裤
=========================
通过summer工厂制作3件短袖
通过summer工厂制作3件短裤
=========================
通过winter工厂制作4件毛衣
通过winter工厂制作4件棉裤

因为是通过抽象接口工厂实现不同的工厂,从而得到不同工厂生产不同的衣服,这种结构称为抽象工厂模式。

2 抽象工厂模式原理

《大话设计模式》中这样定义抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。我们再来看看工厂方法的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类;对比两个概念,可知抽象工厂的核心在于创建多个相关的对象,而工厂方法在于创建一个对象;所以抽象工厂是工厂方法的进阶版。
抽象工厂

3 抽象工厂模式特点

抽象工厂模式的优点有哪些?
在客户端中依赖的是工厂的抽象接口,等到实际使用的时候就是具体的工厂对象,这符合类设计的“依赖倒置原则”,即面向接口编程。
当我们需要新增一个产品,比如鞋的时候,那么只需要给每个工厂造鞋的方法即可;当需要新增一个秋季工厂的时候,只需要继承抽象的工厂接口;客户端对于工厂的改变和产品的感知几乎为零,它只需要知道有这个工厂存在即可。抽象工厂同样符合“开闭原则”和“单一职责原则”
抽象工厂模式有什么缺点呢?
虽然抽象工厂模式符合类的很多设计原则,但是也带有一定的复杂,新增加一个产品需要修改接口工厂,实体工厂类,还要直接新增产品类,一系列的操作显得很复杂,这个缺点也是伴随着“开闭原则”和“单一职责原则”来的。

4 抽象工厂模式适用场景

只有在合适的场景选择不同的设计模式。比如比较稳定且单个产品的场景可以选择简单工厂或者工厂方法模式,而对于实际比较复杂且易变动产品的场景可以选择抽象工厂模式。

5 参考资料

《大话设计模式》
http://www.runoob.com/design-pattern/abstract-factory-pattern.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值