设计模式之工厂模式 设计模式工厂模式案例
yuyutoo 2024-10-15 17:01 4 浏览 0 评论
在程序中类是表示客观世界存在的某类群体的一些基本特征的抽象,对象就是一个个具体的东西,也可以理解为类的一个具体实例。
工厂模式属于创建型模式,它提供一种创建对象的方式。
单一职责原则要求:类的职责要单一,不能将太多的职责放在一个类中,也就是一个接口或者类只能有一个职责。
拿一个对象来说,他有哪些职责呢?
1、本身职责:对象本身具有的属性和行为
2、创建职责:创建这个对象的职责
3、使用职责:使用这个对象的职责
我们一般写程序,客户端会把创建职责和使用职责耦合在一起。
工厂模式就是把对象的创建过程独立,与对象的使用过程解耦。
在实际项目过程中,不是说遇到对象创建我们就要使用工厂模式,需要生成复杂对象的时候,适合使用工厂模式;而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式,使用工厂模式,会增加系统的复杂度。
工厂模式有三种,分别是简单工厂模式,工厂方法模式,抽象工厂模式。
下面用一个汽车的例子分别进行说明,假设有奥迪,宝马,奔驰3种车型。
它们的类图如下:
示例代码:
/**
* 车的接口
*/
public interface ICar {
public abstract String run(); //奔跑
}
public class Audi implements ICar {
@Override
public String run() {
return "奥迪在跑,突破科技,启迪未来!";
}
}
public class Bmw implements ICar {
@Override
public String run() {
return "宝马车跑,无处不担当!";
}
}
public class Benz implements ICar {
@Override
public String run() {
return "奔驰在跑,心所向,驰以恒!";
}
}
1
简单工厂模式示例
把对象的创建集中到一个工厂类里,通过判断不同的配置进行不同对象的创建。
优点:类的构造方法改变时,只需要修改简单工厂类即可,客户端调用处不需要修改。
缺点:客户端需要了解工厂类的具体实现,如果配置错误,客户端则得不到想要的对象。
示例代码:
/**
* 简单工厂模式
*/
public class SimpleFactory {
public ICar getCar(String className) {
ICar car = null;
if ("Audi".equals(className)) {
car = new Audi();
} else if ("Bmw".equals(className)) {
car = new Bmw();
} else if ("Benz".equals(className)) {
car = new Benz();
}
return car;
}
}
/**
* 测试简单工厂
*/
public class TestSimpleFactory {
public static void main(String[] args) {
SimpleFactory carFactory = new SimpleFactory();
ICar audi = carFactory.getCar("Audi");
System.out.println(audi.run());
ICar bmw = carFactory.getCar("Bmw");
System.out.println(bmw.run());
ICar benz = carFactory.getCar("Benz");
System.out.println(benz.run());
}
}
运行结果:
奥迪在跑,突破科技,启迪未来!
宝马在跑,无处不担当!
奔驰在跑,心所向,驰以恒!
2
工厂方法模式
有一个工厂的接口,用于生成对象,每个对象的实际生成放到自己的工厂类中。
优点:对象的创建过程发生变化时,只需要修改它自己的工厂类即可,不对其他类产生影响,符合开闭原则。
缺点:每有一个类,就需要一个工厂类,对于简单对象的创建,反而更复杂了。
类图:
示例代码:
/**
* 工厂接口类
*/
public interface ICarFactory {
public abstract ICar getCar();
}
/**
* Audi工厂,创建Audi对象
*/
public class AudiFactory implements ICarFactory {
@Override
public ICar getCar() {
return new Audi();
}
}
/**
* Bmw工厂,创建Bmw对象
*/
public class BmwFactory implements ICarFactory {
@Override
public ICar getCar() {
return new Bmw();
}
}
/**
* Benz工厂,创建Benz对象
*/
public class BenzFactory implements ICarFactory {
@Override
public ICar getCar() {
return new Benz();
}
}
/**
* 测试工厂方法模式
*/
public class TestFactory {
public static void main(String[] args) {
ICarFactory audiFactory = new AudiFactory();
System.out.println(audiFactory.getCar().run());
ICarFactory bmwFactory = new BmwFactory();
System.out.println(bmwFactory.getCar().run());
ICarFactory benzFactory = new BenzFactory();
System.out.println(benzFactory.getCar().run());
}
}
运行结果:
奥迪在跑,突破科技,启迪未来!
宝马在跑,无处不担当!
奔驰在跑,心所向,驰以恒!
3
抽象工厂模式
使用抽象类封装创建对象的方法,具体工厂类继承抽象类,并实现具体的创建过程。
优点:抽象类可以写逻辑,把公共的逻辑放到抽象类里,便于管理。
缺点:如果抽象类有多个实现类,那么对抽象类里新增其他抽象方法或删除抽象方法时,实现类也要跟着改动,违背开闭原则。
使用抽象工厂模式的好处是,增加新功能的时候,用户直接可以选择,想用就用,不用也可以。类似于API升级,API方法新增了,用户可以调用,也可以不调用。
类图:
示例代码:
/**
* 抽象汽车工厂
*/
public abstract class AbstractCarFactory {
/**
* 创建Audi对象
*/
public abstract ICar getAudi();
/**
* 创建Bmw对象
*/
public abstract ICar getBmw();
/**
* 创建Benz对象
*/
public abstract ICar getBenz();
}
/**
* 具体汽车工厂
*/
public class CarFactory extends AbstractCarFactory {
@Override
public ICar getAudi() {
return new Audi();
}
@Override
public ICar getBmw() {
return new Bmw();
}
@Override
public ICar getBenz() {
return new Benz();
}
}
/**
* 测试抽象工厂模式
*/
public class TestAbstractFactory {
public static void main(String[] args) {
CarFactory carFarctory = new CarFactory();
System.out.println(carFarctory.getAudi().run());
System.out.println(carFarctory.getBmw().run());
System.out.println(carFarctory.getBenz().run());
}
}
运行结果:
奥迪在跑,突破科技,启迪未来!
宝马在跑,无处不担当!
奔驰在跑,心所向,驰以恒!
抽象类和接口的区别:
1、接口不能写逻辑
2、抽象类可以写逻辑,除了接口方法,还可以写普通公共方法。
4
结束语
工厂模式是设计模式中的创建型模式,它是用来创建对象的,工厂模式一般有三种:
1、简单工厂模式
2、工厂方法模式
3、抽象工厂模式
当我们创建一个对象的时候,构造方法里需要传入参数的时候,一般就要考虑是否选用工厂模式,选用哪种工厂模式了。
运用工厂模式的好处就是当你构造方法参数变化的时候,使用工厂模式后,修改起来非常简单,只需要修改工厂即可;如果没有工厂模式,那么客户端调用的地方,创建对象的地方都需要改动。
相关推荐
- 史上最全的浏览器兼容性问题和解决方案
-
微信ID:WEB_wysj(点击关注)◎◎◎◎◎◎◎◎◎一┳═┻︻▄(页底留言开放,欢迎来吐槽)●●●...
-
- 平面设计基础知识_平面设计基础知识实验收获与总结
-
CSS构造颜色,背景与图像1.使用span更好的控制文本中局部区域的文本:文本;2.使用display属性提供区块转变:display:inline(是内联的...
-
2025-02-21 16:01 yuyutoo
- 写作排版简单三步就行-工具篇_作文排版模板
-
和我们工作中日常word排版内部交流不同,这篇教程介绍的写作排版主要是用于“微信公众号、头条号”网络展示。写作展现的是我的思考,排版是让写作在网格上更好地展现。在写作上花费时间是有累积复利优势的,在排...
- 写一个2048的游戏_2048小游戏功能实现
-
1.创建HTML文件1.打开一个文本编辑器,例如Notepad++、SublimeText、VisualStudioCode等。2.将以下HTML代码复制并粘贴到文本编辑器中:html...
- 今天你穿“短袖”了吗?青岛最高23℃!接下来几天气温更刺激……
-
最近的天气暖和得让很多小伙伴们喊“热”!!! 昨天的气温到底升得有多高呢?你家有没有榜上有名?...
- CSS不规则卡片,纯CSS制作优惠券样式,CSS实现锯齿样式
-
之前也有写过CSS优惠券样式《CSS3径向渐变实现优惠券波浪造型》,这次再来温习一遍,并且将更为详细的讲解,从布局到具体样式说明,最后定义CSS变量,自定义主题颜色。布局...
- 你的自我界限够强大吗?_你的自我界限够强大吗英文
-
我的结果:A、该设立新的界限...
- 行内元素与块级元素,以及区别_行内元素和块级元素有什么区别?
-
行内元素与块级元素首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block)、行内(inline)。块级元素:(以下列举比较常...
-
- 让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华
-
去年的两会期间,习近平总书记在参加人大会议四川代表团审议时,对治蜀兴川提出了明确要求,指明了前行方向,并带来了“祝四川人民的生活越来越安逸”的美好祝福。又是一年...
-
2025-02-21 16:00 yuyutoo
- 今年国家综合性消防救援队伍计划招录消防员15000名
-
记者24日从应急管理部获悉,国家综合性消防救援队伍2023年消防员招录工作已正式启动。今年共计划招录消防员15000名,其中高校应届毕业生5000名、退役士兵5000名、社会青年5000名。本次招录的...
- 一起盘点最新 Chrome v133 的5大主流特性 ?
-
1.CSS的高级attr()方法CSSattr()函数是CSSLevel5中用于检索DOM元素的属性值并将其用于CSS属性值,类似于var()函数替换自定义属性值的方式。...
- 竞走团体世锦赛5月太仓举行 世界冠军杨家玉担任形象大使
-
style="text-align:center;"data-mce-style="text-align:...
- 学物理能做什么?_学物理能做什么 卢昌海
-
作者:曹则贤中国科学院物理研究所原标题:《物理学:ASourceofPowerforMan》在2006年中央电视台《对话》栏目的某期节目中,主持人问过我一个的问题:“学物理的人,如果日后不...
-
- 你不知道的关于这只眯眼兔的6个小秘密
-
在你们忙着给熊本君做表情包的时候,要知道,最先在网络上引起轰动的可是这只脸上只有两条缝的兔子——兔斯基。今年,它更是迎来了自己的10岁生日。①关于德艺双馨“老艺...
-
2025-02-21 16:00 yuyutoo
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)