网站首页 > java教程 正文
工厂模式分为简单工厂模式、工厂方法模式和抽象工厂模式三种。
工厂模式的特点:用户不用关心对象如何创建,只需要消费对象即可。
工厂模式都属于创建型模式。
创建型模式:抽象了类的实例化,将类的创建和使用解耦,外界只需要知道统一的调用接口,不需要关心具体创建过程。
简单工厂模式
又叫静态工厂模式,不属于23种设计模式,是工厂模式的一种特殊实现。
通过传递参数,动态决定创建哪一种类型实例。
包括三种角色。
工厂角色:简单工厂模式的核心,创建具体产品角色的核心逻辑。外界可以直接调用工厂类,创建需要的对象,一般是通过传递不同的参数,确定不同的对象。
抽象产品角色:具体产品实例的父类(接口)
具体产品角色:工厂模式最终创建的具体产品实例
示例
我们以《斗罗大陆》里面魂师获取魂环为例。
魂师修炼到一定等级之后,需要通过魂环获得魂技,魂环由魂兽产生,魂兽生活在星斗大森林里,魂师通过在星斗大森林里猎杀魂兽获得魂环。
我们可以这样认为:
星斗大森林就相当于一个产生各种魂环的工厂,扮演工厂角色。
魂环有十年、百年、千年、万年、十万年等,不同年限的魂环由不同的魂兽产生,那么魂兽就相当于产生魂环的抽象产品,而魂环则是具体的产品。
魂师进入星斗大森林工厂,根据自己需要获取不同年限的魂环。
代码示例
魂师有两个属性姓名和武魂。(代码太多占空间,只显示核心代码)
/**
* 魂师
*/
public class SoulMaster {
String name;//姓名
String soulWu;//武魂
}
抽象产品,魂兽产生魂环接口
/**
* 魂兽产生魂环接口
*/
public interface SoulBest {
//魂兽可以产生魂环
String produceSouleRing();
}
具体产品,魂环:十年、百年、千年、万年、十万年,凶兽魂环,百万年魂环
public class SoulRing10 implements SoulBest{
@Override
public String produceSouleRing() {
return "十年魂环";
}
}
public class SoulRing100 implements SoulBest{
@Override
public String produceSouleRing() {
return "百年魂环";
}
}
public class SoulRing1w implements SoulBest{
@Override
public String produceSouleRing() {
return "万年魂环";
}
}
//此处省略很多魂环代码
星斗大森林,产生魂环的工厂
//星斗大森林相当于产生魂环的工厂
public class StarsForestFactory {
public static SoulBest getSoulRing(int year) {
//猎杀不同年限魂兽,获得不同的魂环
SoulBest soulBest = null;
if (year >= 0 && year <= 100) {
soulBest = new SoulRing10();//十年魂环
} else if (year > 100 && year < 1000) {
soulBest = new SoulRing100();//百年魂环
} else if (year >=1000 && year < 10000) {
soulBest = new SoulRing1k();//千年魂环
}else if (year >=10000 && year < 100000) {
soulBest = new SoulRing1w();//万年魂环
}else if (year >=100000 && year < 200000) {
soulBest = new SoulRing10w();//十万年魂环
}else if (year >=200000 && year < 1000000) {
soulBest = new SoulRing10wplus();//凶兽魂环
}else if (year >=1000000) {
soulBest = new SoulRing100w();//百万年魂环
}
return soulBest;
}
}
给我们的魂师们获取魂环
public class GetSoulRing {
public static void main(String[] args) {
//创建魂师
ArrayList<SoulMaster> sms = new ArrayList<>();
sms.add(new SoulMaster("唐三","昊天锤"));
sms.add(new SoulMaster("霍雨浩","灵眸"));
sms.add(new SoulMaster("唐舞麟","蓝银皇"));
sms.add(new SoulMaster("蓝轩宇","银纹蓝银皇"));
SoulBest soulBest;
int soulRingYear = 0;
for(SoulMaster sm : sms){
soulRingYear=random();//随即生成需要获取的魂环年限
soulBest = StarsForestFactory.getSoulRing(soulRingYear);
System.out.println(sm.getName()+"为武魂【"+sm.getSoulWu()
+"】获取了【"+soulBest.produceSouleRing()+"】");
}
}
}
运行结果
唐三为武魂【昊天锤】获取了【千年魂环】
霍雨浩为武魂【灵眸】获取了【十年魂环】
唐舞麟为武魂【蓝银皇】获取了【十年魂环】
蓝轩宇为武魂【银纹蓝银皇】获取了【千年魂环】
简单工厂的缺点是:所有的逻辑都写在工厂类,如果产品多,会很臃肿,添加新产品需要修改工厂类。
适用创建对象不多的场景。
工厂方法模式
简单工厂模式里面,工厂方法是静态属性,不能被继承重写。
工厂方法模式,提供一个抽象工厂角色,由抽象工厂的子类进行具体的逻辑处理。将对象的创建推迟到子类中。避免了简单工程模式中,工厂类可能会出现的臃肿问题。
包括四种角色。
抽象工厂角色:工厂方法模式的核心,同应用程序无关,具体工厂必须继承或实现抽象工厂。
具体工厂角色:包括具体的业务逻辑代码,由具体的产品调用创建。
抽象产品角色:具体产品的父类。
具体产品角色:最终创建的产品实例。
示例
随着魂师不断猎杀魂兽,魂兽濒临灭绝,于是魂师和魂兽之间爆发了战争,而在大战之际,一个划时代意义组织——传灵塔诞生了。
传灵塔创建了魂灵体系,魂灵分为白色、黄色、紫色、黑色、红色、橙色和金色,分别提供十年、百年、千年等不同年限的魂环。
魂灵的出现让魂师不再依靠猎杀魂兽来获取魂环。
我们可以这样认为:
传灵塔相当于一个魂灵制造工厂,工厂下面不同的生产线制造不同类型的魂灵。
传灵塔是抽象工厂,它可以制造任何魂灵。
生产线相当于抽象工厂的子类,负责生产魂师需要的魂灵,是具体的工厂。
魂灵是是提供魂环的抽象产品。
魂环则是魂灵提供的具体产品。
示例代码
抽象产品:魂灵
//魂灵
public interface Soul {
//提供什么类型魂环
String produceSoulRing();
//提供魂环数量
int produceSoulRingNum();
}
具体产品:不同类型的魂灵
public class Soul10 implements Soul{
@Override
public String produceSoulRing() {
return "白色魂灵";
}
@Override
public int produceSoulRingNum() {
return 1;
}
}
public class Soul10w implements Soul{
@Override
public String produceSoulRing() {
return "红色魂灵";
}
@Override
public int produceSoulRingNum() {
return 4;
}
}
抽象工厂:传灵塔
public interface SoulPagodaFactory {
Soul makeSoul();//制造魂灵
}
具体工厂:传灵塔的魂灵生产线
public class SoulPagodaRing10 implements SoulPagodaFactory{
@Override
public Soul makeSoul() {
System.out.println("制造白色魂灵");
return new Soul10();
}
}
public class SoulPagodaRing1w implements SoulPagodaFactory{
@Override
public Soul makeSoul() {
System.out.println("制造黑色魂灵");
return new Soul1w();
}
}
魂师进入传灵塔购买需要的魂灵获取魂环
//唐三想要购买万年魂灵
SoulPagodaRing1w sp1w = new SoulPagodaRing1w();
Soul s1 = sp1w.makeSoul();
System.out.println("唐三购买【"+s1.produceSoulRing()+"】可以提供"
+s1.produceSoulRingNum()+"个魂环");
//霍雨浩想要购买凶兽魂灵
SoulPagodaRing10wp sp10wp = new SoulPagodaRing10wp();
Soul s2 = sp10wp.makeSoul();
System.out.println("霍雨浩购买【"+s2.produceSoulRing()+"】可以提供"
+s2.produceSoulRingNum()+"个魂环");
//唐舞麟想要购买十万年魂灵
SoulPagodaRing10w sp10w = new SoulPagodaRing10w();
Soul s3 = sp10w.makeSoul();
System.out.println("唐舞麟购买【"+s3.produceSoulRing()+"】可以提供"
+s3.produceSoulRingNum()+"个魂环");
//蓝轩宇想要购买百万年魂灵
SoulPagodaRing100w sp100w = new SoulPagodaRing100w();
Soul s4 = sp100w.makeSoul();
System.out.println("蓝轩宇购买【"+s4.produceSoulRing()+"】可以提供"
+s4.produceSoulRingNum()+"个魂环");
运行结果
制造黑色魂灵
唐三购买【黑色魂灵】可以提供4个魂环
制造橙色魂灵
霍雨浩购买【橙色魂灵】可以提供12个魂环
制造红色魂灵
唐舞麟购买【红色魂灵】可以提供4个魂环
制造金色魂灵
蓝轩宇购买【红色魂灵】可以提供4个魂环
抽象工厂模式
创建一系列对象,而无需指定具体的实现类。
抽象工厂模式是工厂方法模式的升级,同样包括抽象工厂、具体工厂、抽象产品、具体产品四种角色。
相比工厂方法模式:
抽象工厂模式针对的是多个产品的等级结构,而工厂方法模式只是针对一个产品的等级结构。
抽象工厂模式中产品衍生于不同的接口或抽象类,而工厂方法模式衍生于同一个接口或实现类。
工厂方法模式,每增加一个新产品,就需要建立一座新的工厂。例如传灵塔每增加一种新魂灵的供应,就需要开辟新的魂灵生产线。
而抽象工厂模式,相当于在工厂类之上,再抽象出了一个超级工厂,将不同的产品工厂组合在一起,拓展出了产品族的概念,保证用户始终在一个产品组里面获得产品。同时,也方便管理者对于产品的约束管理。
所以,对于抽象工厂:
提供创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
示例
随着时代的发展,斗罗大陆上出现了无数新的职业,比如魂师、机甲师、锻造师、战舰指挥等,作为大陆第一学院的史莱克学院,同样需要与时俱进,不能只培养魂师。
这就形成一个类似抽象工厂模式的例子。
我们把学校提取出来,上升一下,担任抽象工厂的角色。
斗罗大陆不可能只有一座学院,一座学院也不可能只教授一种职业。
所以,大陆上不仅有史莱克学院,还有日月皇家魂导师学院。这就是具体工厂的角色。
同样,不同的人从事不同的职业,来自不同的学院。
这些职业就是抽象的产品,而每个人就是具体的产品。
示例代码
先创建学校的接口,有两个方法培养魂师,培养机甲师。
public interface University {
SoulMaster trainSoulMaster();//培养魂师
Mecha trainMecha();//培养机甲师
}
分别创建史莱克学院和日月皇家魂导师学院
//史莱克学院
public class ShrekUiversity implements University{
@Override
public SoulMaster trainSoulMaster() {
return new ShrekSoulMaster();
}
@Override
public Mecha trainMecha() {
return new ShrekMecha();
}
}
//日月皇家魂导师学院
public class RoyalUniversity implements University{
@Override
public SoulMaster trainSoulMaster() {
return new RoyalSoulMaster();
}
@Override
public Mecha trainMecha() {
return new RoyalMecha();
}
}
创建魂师和机甲师的职业接口
//魂师
public interface SoulMaster {
void getSoulMaster();
}
//机甲师
public interface Mecha {
void getMecha();
}
创建史莱克学院培训出来的魂师和机甲师。
创建日月皇家魂导师学院培训出来的魂师和机甲师。(省略部分代码)
public class ShrekSoulMaster implements SoulMaster{
@Override
public void getSoulMaster() {
System.out.println("史莱克学院的魂师");
}
}
public class RoyalMecha implements Mecha{
@Override
public void getMecha() {
System.out.println("日月皇家魂导师学院的机甲师");
}
}
不同的人进入不同的学院,学习不同的职业。
//创建史莱克学院
ShrekUiversity shrekUiversity = new ShrekUiversity();
//培养魂师
shrekUiversity.trainSoulMaster().getSoulMaster();
//培养机甲师
shrekUiversity.trainMecha().getMecha();
//创建日月皇家魂导师学院
RoyalUniversity royalUniversity = new RoyalUniversity();
//培养魂师
royalUniversity.trainSoulMaster().getSoulMaster();
//培养机甲师
royalUniversity.trainMecha().getMecha();
运行结果
史莱克学院的魂师
史莱克学院的机甲师
日月皇家魂导师学院的魂师
日月皇家魂导师学院的机甲师
猜你喜欢
- 2024-10-23 Java的简单工厂模式(java简单工厂模式实验总结)
- 2024-10-23 Java开发篇——设计模式(3)面试被问工厂模式?不要怕看这里
- 2024-10-23 架构师成长之路:Java设计模式之工厂模式
- 2024-10-23 Java的设计模式(十一):三种工厂模式区别,SpringBoot中的运用
- 2024-10-23 Java——工厂方法模式(java的工厂模式是什么意思啊)
- 2024-10-23 Java编程细节——设计模式之工厂模式
- 2024-10-23 Java之工厂方法(Factory Method)(java工厂模式的应用场景)
- 2024-10-23 Java工厂设计模式学习笔记(详细总结)
- 2024-10-23 教你轻松学Java开发23种设计模式 --工厂设计模式
- 2024-10-23 java设计模式-创建者模式-工厂模式
你 发表评论:
欢迎- 最近发表
-
- Java常量定义防暴指南:从"杀马特"到"高富帅"的华丽转身
- Java接口设计原则与实践:优雅编程的艺术
- java 包管理、访问修饰符、static/final关键字
- Java工程师的代码规范与最佳实践:优雅代码的艺术
- 编写一个java程序(编写一个Java程序计算并输出1到n的阶乘)
- Mycat的搭建以及配置与启动(mycat部署)
- Weblogic 安装 -“不是有效的 JDK Java 主目录”解决办法
- SpringBoot打包部署解析:jar包的生成和结构
- 《Servlet》第05节:创建第一个Servlet程序(HelloSevlet)
- 你认为最简单的单例模式,东西还挺多
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)