[java设计模式]工厂设计模式,给对象一个合法的生产渠道。
引言
在实际的项目中,随着我们的对象越来越多。管理的难度也越来越大。这时候怎么办呢?使用Spring容器呀!没错Spring容器也是用到了工厂设计模式。所以,我们今天就来学习一下工厂设计模式。
工厂设计模式
何为工厂设计模式?
根据名称来理解,什么是工厂?工厂就是有一堆流水线,来生产某一类的产品。假设:我们现在需要一瓶洗发水,来呵护一下我们秀美的头发。于是我们亲自动手做了一瓶海飞丝洗发水。用了一段时间之后,我们发现自己的头发越来越少。这个时候,我们继续一瓶
霸王防脱洗发水,我们总不能每次都自己手动做一瓶,费时费力,还不见的效果好。那怎么办呢?当然让工厂去负责生产洗发水,我们直接通过购买获得就OK。
工厂设计模式应用场景
在写程序中,我们需要去创建某一类的一系列对象。比如:如上述,我们需要各种各样的洗发水,它们都同属于洗发水一类。
工厂设计模式的特征:
- 调用者想创建对象,只需要调用对应的API即可。
- 扩展性强,需要增加一个产品,只需要扩展一个工厂类即可。
- 屏蔽产品的具体实现,调用者只关心产品的接口。
常见的工厂设计模式:
- 简单工厂
- 工厂方法
- 抽象工厂
具体代码实现如下:
简单工厂
简单工厂,就是通过逻辑判断,返回相应的对象。严格意义来讲,如果我们要进行扩展的时候违背了开闭原则。工作中,不建议使用,耦合性太强了。
/**
* 洗发水产品的接口
*/
interface Shampoo {
//... 一些洗发水的特性
}
/**
* 海飞丝的洗发水具体实现
*/
class HeadShouldersShampoo implements Shampoo {
//... 海飞丝洗发水的特性
}
/**
* 霸王洗发水的具体实现
*/
class BAWANGShampoo implements Shampoo {
//... 霸王洗发水的特性
}
/**
* 清扬洗发水的具体实现
*/
class ClearShampoo implements Shampoo {
//... 清扬洗发水的特性
}
/**
* 洗发水工厂
*/
class ShampooFactory {
// 提供对外获取Shampoo的API
public static Shampoo getShampoo(String shampooName) {
// 获取海飞丝洗发水对象
if ("HeadShouldersShampoo".equalsIgnoreCase(shampooName)) {
return new HeadShouldersShampoo();
// 获取霸王洗发水对象
} else if ("BAWANGShampoo".equalsIgnoreCase(shampooName)) {
return new BAWANGShampoo();
// 获取清扬洗发水对象
} else if ("ClearShampoo".equalsIgnoreCase(shampooName)) {
return new ClearShampoo();
}
return null;
}
}
/**
* @ClassName : SimpleFactory
* @Description : 简单工厂
*/
public class SimpleFactory {
public static void main(String[] args) {
// 获取海飞丝洗发水对象
Shampoo headShouldersShampoo = ShampooFactory.getShampoo("HeadShouldersShampoo");
if (headShouldersShampoo instanceof HeadShouldersShampoo){
System.out.println("获取海飞丝洗发水对象成功");
}
// 获取霸王洗发水对象
Shampoo bawangShampoo = ShampooFactory.getShampoo("BAWANGShampoo");
if (bawangShampoo instanceof BAWANGShampoo){
System.out.println("获取霸王洗发水对象成功");
}
// 获取清扬洗发水对象
Shampoo clearShampoo = ShampooFactory.getShampoo("ClearShampoo");
if (clearShampoo instanceof ClearShampoo){
System.out.println("获取清扬洗发水对象成功");
}
}
}
工厂方法
我们依然站在生活的角度去理解,简单工厂,就是一个工厂,来生产各种各样的洗发水。但现实生活中,这样有不操作是不现实的。我们一般会用一个工厂来生产海飞丝洗发水,一个工厂来生产霸王洗发水,一个工厂来生产清扬洗发水。此时,我们如果要新增一个品牌的洗发水,只需要增加一个工厂就好了。
// 洗发水接口
interface Shampoo{
// ... 洗发水共有的特性
}
/**
* 海飞丝的洗发水具体实现
*/
class HeadShouldersShampoo implements Shampoo {
//... 海飞丝洗发水的特性
}
/**
* 霸王洗发水的具体实现
*/
class BAWANGShampoo implements Shampoo {
//... 霸王洗发水的特性
}
/**
* 清扬洗发水的具体实现
*/
class ClearShampoo implements Shampoo {
//... 清扬洗发水的特性
}
/**
* 抽象出洗发水工厂共有的特性
*/
interface ShampooFactory{
// 生产一瓶洗发水
Shampoo getShampoo();
}
/**
* 海飞丝洗发水工厂,主要负责生产海飞丝品牌的洗发水
*/
class HeadShouldersShampooFactory implements ShampooFactory{
@Override
public Shampoo getShampoo() {
return new HeadShouldersShampoo();
}
}
/**
* 霸王洗发水工厂,主要负责生产霸王品牌的洗发水
*/
class BAWANGShampooFactory implements ShampooFactory{
@Override
public Shampoo getShampoo() {
return new BAWANGShampoo();
}
}
/**
* 清扬洗发水工厂,主要负责生产清扬品牌的洗发水
*/
class ClearShampooFactory implements ShampooFactory{
@Override
public Shampoo getShampoo() {
return new ClearShampoo();
}
}
/**
* @ClassName : FactoryMethod
* @Description : 工厂方法
*/
public class FactoryMethod {
public static void main(String[] args) {
// 获取海飞丝洗发水,首先获取海飞丝的工厂,在获取海飞丝洗发水对象。
// 这里肯定有小伙伴会疑惑,宁愿 new 一个海飞丝工厂,为何不直接new 海飞丝对象呢?
// 其实结合单例设计模式,这个你可以把海飞丝工厂写成单例,就不会重复的new 海飞丝工厂了。
Shampoo shampoo = new HeadShouldersShampooFactory().getShampoo();
if (shampoo instanceof HeadShouldersShampoo){
System.out.println("获取海飞丝洗发水对象成功");
}
// 获取霸王洗发水对象
Shampoo shampoo1 = new BAWANGShampooFactory().getShampoo();
if (shampoo1 instanceof BAWANGShampoo){
System.out.println("获取霸王洗发水对象成功");
}
// 获取清扬洗发水对象
Shampoo shampoo2 = new ClearShampooFactory().getShampoo();
if (shampoo2 instanceof ClearShampoo){
System.out.println("获取清扬洗发水对象成功");
}
}
}
抽象工厂
抽象工厂,这个名字起的都很抽象。不要好理解。比较官方一点的解释:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。读起来都有点拗口。那就讲一下本博主怎么去理解?我们依然拿来生产一瓶洗发水为例子。一瓶洗发水,大致是由包装和液体组成的,在实际的生产工作中,我们不可能串行的去生产,这样太浪费时间了。于是乎,我们为了生产一瓶洗发水,就最少开两条流水线,一条生产液体,一条生产瓶子,又因为大部分的洗发水,都是由和这个两部分组成的,所以我们需要将生产液体和生产瓶子抽象出来,由每个品牌洗发水自己的流水线来实现。
import java.util.List;
/**
* 定义洗发水接口
*/
interface Shampoo {
// 设置洗发水的液体
void setLiquid();
// 设置洗发水的瓶子
void setBox();
}
/**
* 海飞丝的洗发水具体实现
*/
class HeadShouldersShampoo implements Shampoo {
@Override
public void setLiquid() {
System.out.println("设置海飞丝洗发水有液体");
}
@Override
public void setBox() {
System.out.println("设置海飞丝洗发水的包装");
}
//... 海飞丝洗发水的特性
}
/**
* 霸王洗发水的具体实现
*/
class BAWANGShampoo implements Shampoo {
@Override
public void setLiquid() {
System.out.println("设置霸王洗发水液体");
}
@Override
public void setBox() {
System.out.println("设置霸王洗发水的包装");
}
//... 霸王洗发水的特性
}
/**
* 清扬洗发水的具体实现
*/
class ClearShampoo implements Shampoo {
@Override
public void setLiquid() {
System.out.println("设置清扬洗发水液体");
}
@Override
public void setBox() {
System.out.println("设置清扬洗发水的包装");
}
//... 清扬洗发水的特性
}
/**
* 洗发水的液体接口,由各个品牌来实现
*/
interface Liquid {
}
/**
* 海飞丝洗发水的具体实现类
*/
class HeadShouldersShampooLiquid implements Liquid {
}
/**
* 霸王洗发水液体的具体实现类
*/
class BAWANGShampooLiquid implements Liquid {
}
/**
* 清扬洗发水液体的具体实现类
*/
class ClearShampooLiquid implements Liquid {
}
/**
* 洗发水包装接口,有具体品牌的子类来实现
*/
interface Box {
}
/**
* 海飞丝的包装
*/
class HeadShouldersShampooBox implements Box {
}
/**
* 霸王的包装
*/
class BAWANGShampooBox implements Box {
}
/**
* 清扬的包装
*/
class ClearingShampooBox implements Box {
}
/**
* 工厂接口
*/
interface ShampooFactory {
// 生产液体的流水线。
Liquid productionLiquid();
// 生产盒子的流水线。
Box productionBox();
// 生产洗发水,将生产的液体和流水线组装起来。
Shampoo getShampoo(Liquid liquid, Box box);
}
/**
* 海飞丝洗发水的工厂
*/
class HearingShampooFactory implements ShampooFactory {
@Override
public Liquid productionLiquid() {
return new HeadShouldersShampooLiquid();
}
@Override
public Box productionBox() {
return new HeadShouldersShampooBox();
}
@Override
public Shampoo getShampoo(Liquid liquid, Box box) {
return new HeadShouldersShampoo();
}
}
/**
* 霸王洗发水的工厂
*/
class BAWANGShampooFactory implements ShampooFactory {
@Override
public Liquid productionLiquid() {
return new BAWANGShampooLiquid();
}
@Override
public Box productionBox() {
return new BAWANGShampooBox();
}
@Override
public Shampoo getShampoo(Liquid liquid, Box box) {
return new BAWANGShampoo();
}
}
/**
* 清扬洗发水工厂
*/
class ClearingShampooFactory implements ShampooFactory {
@Override
public Liquid productionLiquid() {
return new ClearShampooLiquid();
}
@Override
public Box productionBox() {
return new ClearingShampooBox();
}
@Override
public Shampoo getShampoo(Liquid liquid, Box box) {
return new ClearShampoo();
}
}
/**
* @ClassName : abstractFactory 抽象工厂
* @Description : 抽象工厂
*/
public class abstractFactory {
public static void main(String[] args) {
// 生产一瓶海飞丝的洗发水
// 创建一个海飞丝的工厂
HearingShampooFactory hearingShampooFactory = new HearingShampooFactory();
// 生产海飞丝洗发水液体
Liquid liquid = hearingShampooFactory.productionLiquid();
// 生产海飞丝的包装
Box box = hearingShampooFactory.productionBox();
if (box instanceof HeadShouldersShampooBox && liquid instanceof HeadShouldersShampooLiquid) {
Shampoo shampoo = hearingShampooFactory.getShampoo(liquid, box);
if (shampoo instanceof HeadShouldersShampoo) {
System.out.println("生产海飞丝洗发水成功");
}
}
// 生产一瓶霸王的洗发水
// 创建一个霸王的工厂
BAWANGShampooFactory bawangShampooFactory = new BAWANGShampooFactory();
// 生产霸王洗发水液体
Liquid liquid1 = bawangShampooFactory.productionLiquid();
// 生产霸王的包装
Box box1 = bawangShampooFactory.productionBox();
if (liquid1 instanceof BAWANGShampooLiquid && box1 instanceof BAWANGShampooBox) {
Shampoo shampoo = bawangShampooFactory.getShampoo(liquid1, box1);
if (shampoo instanceof BAWANGShampoo) {
System.out.println("生产霸王洗发水成功");
}
}
// 生产一瓶清扬洗发水
// 创建一个清扬洗发水工厂
ClearingShampooFactory clearingShampooFactory = new ClearingShampooFactory();
// 生产清扬洗发水液体
Liquid liquid2 = clearingShampooFactory.productionLiquid();
// 生产清扬洗发水瓶子
Box box2 = clearingShampooFactory.productionBox();
if (liquid2 instanceof ClearShampooLiquid && box2 instanceof ClearingShampooBox) {
Shampoo shampoo = clearingShampooFactory.getShampoo(liquid2, box2);
if (shampoo instanceof ClearShampoo) {
System.out.println("生产清扬洗发水成功");
}
}
}
}
结尾
工厂设计模式,差不多就这些了。
本作品采用《CC 协议》,转载必须注明作者和本文链接