论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
数据库
›
Mysql
›
设计模式---工厂方法模式
设计模式---工厂方法模式
吴旭华
论坛元老
|
2022-9-30 22:30:22
|
显示全部楼层
|
阅读模式
楼主
主题
1018
|
帖子
1018
|
积分
3054
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
简述
类型:创建型
目的:实现对客户端中
对象的平替
。
我们借以下案例来说说如何使用工厂方法模式平替对象。
优化案例
最初版
public interface OS {
public void start();
public void sleep();
public void restart();
public void stop();
}
public class Linux implements OS {
public void start() {
System.out.println("启动Linux系统!");
}
public void sleep() {
System.out.println("睡眠Linux系统!");
}
public void restart() {
System.out.println("重启Linux系统!");
}
public void stop() {
System.out.println("停止Linux系统!");
}
}
public class Windows implements OS {
public void start() {
System.out.println("启动Windows系统!");
}
public void sleep() {
System.out.println("睡眠Windows系统!");
}
public void restart() {
System.out.println("重启Windows系统!");
}
public void stop() {
System.out.println("停止Windows系统!");
}
}
public class Unix implements OS {
public void start() {
System.out.println("启动Unix系统!");
}
public void sleep() {
System.out.println("睡眠Unix系统!");
}
public void restart() {
System.out.println("重启Unix系统!");
}
public void stop() {
System.out.println("停止Unix系统!");
}
}
复制代码
客户端调用如下。
public class Client {
public static void main(String[] args) {
OS os1 = new Linux();
OS os2 = new Windows();
OS os3 = new Unix();
}
}
复制代码
传统是new创建对象的方式有着硬编码的问题。当我们需要把所有Linux对象改为Unix对象时,就必须在项目中检索所有的Linux一一修改为Unix。这无疑增加了大量的无意义的工作。
修改版v1(简单工厂模式)
增加一个工厂类,其他不变。
public class OSFactory {
static OS instance(String arg) {
if (arg.equals("Linux")) {
return new Linux();
} else if (arg.equals("Unix")) {
return new Unix();
} else if (arg.equals("Windows")) {
return new Windows();
}
throw new Exception("输入的参数错误");
}
}
复制代码
修改后,客户端的代码调用。
public class Client {
public static void main(String[] args) {
OS os1 = OSFactory.instance("Linux");
OS os2 = OSFactory.instance("Windows");
OS os3 = OSFactory.instance("Unix");
}
}
复制代码
在一定程度上解决了客户端硬编码问题。并且当我们需要把所有Linux对象改为Unix对象时,只需要在OS中将new Linux() → new Unix()即可。这无疑节省了很多的时间,也无需为硬编码带来的大量改修而苦恼。
但是目前这个优化方案依然有至少两个问题,一是OSFactory.instance方法中耦合了所有的OS实现类,这可能有碍于未来的项目维护,二是new Linux() → new Unix()这种修改方式会导致代码变得不明确,既然不论是Linux还是Unix都直接生成Unix对象,就没有必要定义Linux了呀。实际上是因为客户端代码中还有使用OSFactory.instance("Linux")来创建的对象,为了不修改客户端代码,强行做如上修改。
修改版v2(工厂方法模式)
将原本的工厂类抽象化,并定义一系列不同的实现类,其余不变。
public interface OSFactory {
OS create();
}
public class LinuxFactory {
public OS create() {
return new Linux();
}
}
public class WindowsFactory {
public OS create() {
return new Windows();
}
}
public class UnixFactory {
public OS create() {
return new Unix();
}
}
复制代码
修改后,客户端的代码调用。
public class Client {
public static void main(String[] args) {
OSFactory factory = new LinuxFactory();
OS os1 = factory.create();
}
}
复制代码
将原本OSFactory类中臃肿的逻辑分散到各个子类中,提高了系统的可维护性,不用再每次都修改Factory类了。
那么,问题来了,这样的结构对于我们的项目有什么帮助吗?几乎没有,我们只是将对象的创建统一管理了而已,这也只是工厂方法模式的一个很小的功能。实际上需求是快速的将系统中的对象平替。而为了实现这个需求,我们需要结合Java反射这项技术。请看下面的代码。
修改版v3(工厂方法+反射)
只修改客户端的调用方式,其他位置不做修改。
public class Client {
public static void main(String[] args) {
// 实际项目中一般定义成特定的类(专门用来加载各种配置)中的静态变量
Properties prop = new Properties();
FileReader fileReader = new FileReader("src/resource/props/config.prop");
// 使用properties文件来存储当前调用类的信息
prop.load(fileReader);
fileReader.close();
OSFactory factory = (OSFactory) Class.forName(prop.getProperty("FACTORY"))
.getDeclaredConstructor().newInstance();
OS os1 = factory.create();
}
}
复制代码
增加一个properties文件文件,定义如下。
#当前使用的工厂类
FACTORY=design.factorymethod.demo02.LinuxFactory
复制代码
当系统需要将实例的LinuxFactory类转化为其他的实现类时,只需要更改上述配置文件即可。
总结
优点
轻松做到类的平替。
缺点
类数量倍增,系统复杂度增加。
应用场景
根据需求,需要全面替换系统中的某个类时。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
吴旭华
论坛元老
这个人很懒什么都没写!
楼主热帖
【云原生】第二篇--容器管理工具 Docke ...
数据库系统课程设计(高校成绩管理数据 ...
《原CSharp》第二回 巧习得元素分类 子 ...
JVM虚拟机性能监控与故障处理工具(3) ...
使用TrueNas(FreeNas)进行华为手机备 ...
mamba-ssm安装building wheel卡着不动 ...
java中==和equals区别
【图论】—— 有向图的强连通分量 ...
Spark 总复习
AWVS漏洞扫描器的使用
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
DevOps与敏捷开发
程序人生
快速回复
返回顶部
返回列表