您现在的位置是:首页 > 数码 > 

工厂模式 工厂方法模式 抽象工厂模式 简单工厂模式 工厂模式于抽象工厂的区别 设计模式

2025-07-27 13:33:49
工厂模式 工厂方法模式 抽象工厂模式 简单工厂模式 工厂模式于抽象工厂的区别 设计模式 工厂模式 定义一个用于创建对象的接口,让子类实现具体类的创建。工厂将类的实例化延迟的子类。 良好的分装性。对于具体产品,只要知道产品名称即可(类名或字符串),封闭了对产品创建的细节。屏蔽具体产品类。通过抽象产品接口,屏蔽了

工厂模式 工厂方法模式 抽象工厂模式 简单工厂模式 工厂模式于抽象工厂的区别 设计模式

工厂模式

定义一个用于创建对象的接口,让子类实现具体类的创建。工厂将类的实例化延迟的子类。

  • 良好的分装性。对于具体产品,只要知道产品名称即可(类名或字符串),封闭了对产品创建的细节。
  • 屏蔽具体产品类。通过抽象产品接口,屏蔽了各个具体产品的实现细节。使用者只关心产品接口就行。比如,java中JDBC的模式,可以很方便的从mysql切换到Oracle。
    工厂方法模式,是典型的解耦框架。高层模块只需要知道产品的抽象类,符合迪米特法则。也符合依赖倒置原则,只依赖产品抽象类。也符合里氏替换原则,使用产品子类替换父产品,没有问题。

工厂方法模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8j7Q6e-1628926566)(imgs/factoryMethodOriginal.PG)]
上图就是工厂方法通用的类图,看起来还是比较简单的。

现在我们通过一个实际的案例来说明一下。我们模拟一下手机的制造过程。

按照通用类图,我们先创一个抽象的工程类: FactoryPhoneAbstract。

public abstract class FactoryPhoneAbstract {public abstract <T extends Phone> T manufacturePhone(Class<T> c);
}

抽象工厂的实现类,例如我们创建一个比亚迪工厂FactoryBYD,实现了抽象类的制造手机方法。这里我们通过反射的方式来实现。
当然这里的工厂创建的对象比较交单,真实的场景中,可能会比较复杂,步骤较多。所以更加有必要将对象的创建分装在工程里。

public class FactoryBYD extends FactoryPhoneAbstract {@Overridepublic <T extends Phone> T manufacturePhone(Class<T> c) {Phone phone = null;try {phone = (T) Class.forame(c.getame()).newInstance();} catch (Exception e) {e.printStackTrace();}return (T) phone;}
}

接下来我们创建产品Pone接口。这里我们只创建一个打电话的方法call()。

public interface Phone {void call();
}

接着创建三个具体的手机类: PhoneVivo、PhoneHuaWei、PhoneXiaoMi。

public class PhoneHuaWei implements Phone {@Overridepublic void call() {println(华为手机打电话);}
}public class PhoneVivo implements Phone {@Overridepublic void call() {println(Vivo手机打电话);}
}public class PhoneXiaoMi implements Phone {@Overridepublic void call() {println(小米手机打电话);}
}

下面我们创建一个测试类,测试一下。

public class MethodOriginalMain {public static void main(String[] args) {FactoryPhoneAbstract factory = new FactoryBYD();Phone xiaoMi = ();();Phone vivo = ();();Phone huaWei = ();();}}

通过测试案例我们可以看到,在具体使用某个名牌手机时,
我们只需要告诉工厂手机品牌即可,不用关系具体的手机时怎么生产出来。
否则,我们就得自己一个去创建不同的手机对象,包括具体细节都得使用者自行处理。
这样耦合性太强,后期维护和扩展都会很麻烦。

我们现在把所有类的关系UML梳理一下,如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oqKmtWmk-1628926569)(imgs/factoryMethodOriginal2.PG)]
通过类图我们可以看出。通过FactoryBYD工厂实现类,
我们可以把创建三个不同手机对象的具体细节,都延迟到三个手机类的各自实现中去。
对于使用手机对象的用户来说,它只要关心Phone接口的打电话方法即可,
不用关系各品牌手机是怎么实现打电话的功能。
而且很容器在扩展一个新的手机品牌产品。
不需要去修改之前的已发布的代码。

简单工厂模式(静态工厂方法)

工厂方法有些变相的使用方式,例如简单工厂,也叫静态工厂方法。
我们将上面的实现方式稍作变更即可。

第一步,删除FactoryPhoneAbstract抽象类。

第二部,将FactoryBYD修改成如下代码所示。这里我们去掉FactoryBYD的继承类,
将manufacturePhone改成了静态方法
(这也是静态工厂方法名称的由来,当然不改成静态方法也是可以的)。

public class FactoryBYD {public static <T extends Phone> T manufacturePhone(Class<T> c) {Phone human = null;try {human = (T)Class.forame(c.getame()).newInstance();} catch (Exception e) {e.printStackTrace();}return (T) human;}
}

这种改造就相当于是对工厂方法的一种简化改造。我们省去了抽象工作这一部分。

替代单例场景 延迟初始化

抽象工厂模式

我们还是先上一个抽象工厂的类图来看看。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-81adwFIC-16289265648)(imgs/factoryAbstract.PG)]
看上面的类图是不是感觉和工厂方法的类图区别不大。
现在将上面的案例稍微扩展一下。之前比亚迪的代工厂,只为各个品牌手机生产一种类型的手机。
现在如果每个品牌都生产两个版本的手机,一个是旗舰版,一个是青春版。
而且这两个版本的手机是有共性的,有关联的。下面我们就用抽象工厂实现一下这个场景。

创建FactoryPhoneInterface工厂接口,定义三个分别创建小米、华为、vivo三种手机品牌的方法。
相比较工厂方法,这里直接将工厂抽象成接口。当然工厂方法的抽象工厂也是可抽象成接口的。
这里主要的区别,是对不同品牌的手机各自定义了一个方法来完成对手机的构建。

public interface FactoryPhoneInterface {Phone manufactureXiaoMiPhone();Phone manufactureHuaWeiPhone();Phone manufactureVivoPhone();
}

创建Phone接口,相比于之前的场景。这里增加了一个照相功能。

public interface Phone {// 大电话void call();// 照相void photograph();
}

这里我们假设各个品牌手机打电话的功能都是一样的,只有照相的功能不同。
那么接下来,就不直接构建真实的手机对象。我们构建一个抽象的品牌手机类。
将各个品牌打电话的通用功能全部实现。代码如下:

public abstract class PhoneHuaWeiAbs implements Phone {@Overridepublic void call() {println(华为手机打电话);}
}public abstract class PhoneXiaoMiAbs implements Phone {@Overridepublic void call() {println(小米手机打电话);}
}public abstract class PhoneVivoAbs implements Phone {@Overridepublic void call() {println(Vivo手机打电话);}
}

现在各个品牌的抽象类都已构建,而且call方法都实现了。接着,我们创建真实的手机类。

public class HuaWeiFlagship extends PhoneHuaWeiAbs{@Overridepublic void photograph() {println(华为旗舰版手机,一亿像素。);}
}public class HuaWeiYouth extends PhoneHuaWeiAbs{@Overridepublic void photograph() {println(华为青春版手机,一百万像素);}
}public class VivoFlagship extends PhoneVivoAbs{@Overridepublic void photograph() {println(Vivo旗舰版,一亿像素);}
}public class VivoYouth extends PhoneVivoAbs{@Overridepublic void photograph() {println(Vivo青春版,一百万像素);}
}public class XiaoMiFlagship extends PhoneXiaoMiAbs{@Overridepublic void photograph() {println(小米旗舰版,一亿像素);}
}public class XiaoMiYouth extends PhoneXiaoMiAbs{@Overridepublic void photograph() {println(小米青春版,一百万像素);}
}

我们创建了三个品牌的旗舰版、青春版手机,打电话的方法都继承各自品牌没有区别。
只是两个版本的手机像素各有差异。

那么我们怎么用工厂制造这些手机呢。
之前的比亚迪代工厂只需要制造各个品牌的同一种手机,现在不一样了需要两种了。
那么就相当于,在工厂方法中,只有一个车间为各个品牌代工制造手机。
现在,居然有两个类型了。那么我们也就相当于要两个车间,来分别制造。

从代码层面来,就相当于我们需要有两个工厂来生产各个品牌的两种手机。

public class FactoryBYDFlagship implements FactoryPhoneInterface {@Overridepublic Phone manufactureXiaoMiPhone() {return new XiaoMiFlagship();}@Overridepublic Phone manufactureHuaWeiPhone() {return new HuaWeiFlagship();}@Overridepublic Phone manufactureVivoPhone() {return new VivoFlagship();}
}public class FactoryBYDYouth implements FactoryPhoneInterface {@Overridepublic Phone manufactureXiaoMiPhone() {return new XiaoMiYouth();}@Overridepublic Phone manufactureHuaWeiPhone() {return new HuaWeiYouth();}@Overridepublic Phone manufactureVivoPhone() {return new VivoYouth();}
}

这样我们就拥有了两个工厂,分别生产旗舰版、青春版手机。

大家知道,一般旗舰版是高配价格贵销量相对较少,而青春版相对较多。
那么我们就可以通过Client端来协调,制造两台青春版手机,就制造一台旗舰版手机。
这样是为什么需要使用抽象工厂的原因,就是因为,同一产品族是有关联的。

public class FactoryAbsClient {public static void main(String[] args) {FactoryPhoneInterface factoryBYDFlagship = new FactoryBYDFlagship();FactoryPhoneInterface factoryBYDYouth = new FactoryBYDYouth();println(====================旗舰版手机产品线=====================);Phone huaWeiFlagship = ();();huaWeiFlagship.photograph();Phone xiaomiFlagship = ();();xiaomiFlagship.photograph();Phone vivoFlagship = ();();vivoFlagship.photograph();println(=====================青春版手机产品线=================);Phone huaWeiYouth = ();();huaWeiYouth.photograph();Phone xiaomiYouth = ();();xiaomiYouth.photograph();Phone vivoYouth = ();();vivoYouth.photograph();}}

Client端的演示案例就没有按照1:2的量来生产手机了,这里只做测试。

从工厂方法模式和抽象工厂模式的案例,我们可以看出它们的区别:

工厂方法模式针对的是一个产品等级结构;
而抽象工厂模式则是针对的多个相关产品等级结构。

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/shuma/857001.html

相关标签:无
上传时间: 2024-02-10 04:57:45
留言与评论(共有 17 条评论)
本站网友 刘孝英
26分钟前 发表
源站可能有防盗链机制
本站网友 电脑上手机浏览器
11分钟前 发表
那么我们也就相当于要两个车间,来分别制造
本站网友 大黑将志
5分钟前 发表
PhoneHuaWei
本站网友 深圳航空货运
16分钟前 发表
我们省去了抽象工作这一部分
本站网友 dicks
21分钟前 发表
);} }public class HuaWeiYouth extends PhoneHuaWeiAbs{@Overridepublic void photograph() {println(华为青春版手机,一百万像素);} }public class VivoFlagship extends PhoneVivoAbs{@Overridepublic void photograph() {println(Vivo旗舰版,一亿像素);} }public class VivoYouth extends PhoneVivoAbs{@Overridepublic void photograph() {println(Vivo青春版,一百万像素);} }public class XiaoMiFlagship extends PhoneXiaoMiAbs{@Overridepublic void photograph() {println(小米旗舰版,一亿像素);} }public class XiaoMiYouth extends PhoneXiaoMiAbs{@Overridepublic void photograph() {println(小米青春版,一百万像素);} } 我们创建了三个品牌的旗舰版
本站网友 玉米须的药用价值
1秒前 发表
我们将上面的实现方式稍作变更即可
本站网友 协同工作软件
7分钟前 发表
我们构建一个抽象的品牌手机类
本站网友 脸上毛孔粗大
3分钟前 发表
工厂将类的实例化延迟的子类
本站网友 牙痛怎么办
4分钟前 发表
建议将图片保存下来直接上传(img-8j7Q6e-1628926566)(imgs/factoryMethodOriginal.PG)] 上图就是工厂方法通用的类图,看起来还是比较简单的
本站网友 阿弥陀佛故事
10分钟前 发表
那么接下来,就不直接构建真实的手机对象
本站网友 wps2008
29分钟前 发表
public class PhoneHuaWei implements Phone {@Overridepublic void call() {println(华为手机打电话);} }public class PhoneVivo implements Phone {@Overridepublic void call() {println(Vivo手机打电话);} }public class PhoneXiaoMi implements Phone {@Overridepublic void call() {println(小米手机打电话);} } 下面我们创建一个测试类,测试一下
本站网友 本是同根生相煎何太急
26分钟前 发表
从代码层面来,就相当于我们需要有两个工厂来生产各个品牌的两种手机
本站网友 天方地圆
18分钟前 发表
按照通用类图,我们先创一个抽象的工程类: FactoryPhoneAbstract
本站网友 橘子的营养价值
4分钟前 发表
那么就相当于,在工厂方法中,只有一个车间为各个品牌代工制造手机
本站网友 儿童健康网
10分钟前 发表
public class MethodOriginalMain {public static void main(String[] args) {FactoryPhoneAbstract factory = new FactoryBYD();Phone xiaoMi = ();();Phone vivo = ();();Phone huaWei = ();();}} 通过测试案例我们可以看到,在具体使用某个名牌手机时, 我们只需要告诉工厂手机品牌即可,不用关系具体的手机时怎么生产出来
本站网友 血型遗传
25分钟前 发表
源站可能有防盗链机制