功能工厂模式

您是否需要一种非常快速的方法来制作Factory对象? 然后,您需要lambda或其他函数传递! 它不仅快速,而且非常简单。 我敢打赌,如果您对Lambdas相当满意,那么您只需阅读标题就可以做到这一点。 如果您是其中之一,请坚持; 你永远不知道你能学到什么。

附带说明:我正在用Java和Python编写代码示例。 为什么? 因为我喜欢这两种语言,所以为这两种语言放东西肯定不会造成伤害。

工厂模式入门

如果您已经知道什么是工厂设计模式,则可以跳到下一部分。

Factory模式的重点是为对象和方法提供一种实例化对象的方式,而无需暴露所有(或通常是任何一种 )实例化逻辑(需要将哪些内容传递给构造函数)。

举一个愚蠢的例子,假设有一类“ Scientist ,它需要一种方法来产生新的Pen来写下实验数据,但是他不想被创建过程所困扰。 为此,您将为Scientist一个PenFactoryScientist只需知道按一下工厂上的按钮即可获得新的笔。

PenFactory是一个简单的对象,只有一个create()方法,可在每次调用它时提供Pen的新实例。 如果Scientist关心Pen颜色,则可以为他提供ColoredPenFactoryColoredPenFactorycreate()方法也接受颜色参数。 然后, ColoredPenFactory必须弄清楚如何为该笔提供这种颜色。

扩展工厂模式理念

Factory Pattern是面向对象代码的一种模式,因此仅限于OO的工作方式,但是我们可以利用其目的并尝试找到一种以功能方式使其实现的方法,这实际上使它成为了很多更轻松。

实际上,由于缺乏传递函数的能力而创建了许多OO设计模式。 这些中的大多数都可以简单地通过传递函数来替换。 其中的简短列表包括命令,工厂和策略。 如果其他许多人接受函数,则可以删除许多类层次结构。 其中一些模板和访问者。

因此,最大的区别是工厂类不必是一个类。 它也可以是简单的“可调用”。 因此,让我们深入研究一些示例。

OO笔厂

这样就可以看到经典的OO模式和新的功能模式之间的区别,这里是OO Java中的示例类和接口。

public interface Pen {void write(String toWrite);boolean outOfInk();
}public interface PenFactory {Pen create();
}public class Scientist {private PenFactory penerator;private Pen pen;public Scientist(PenFactory penerator) {this.penerator = penerator;this.pen = penerator.create();}public void writeData(String data) {if(pen.outOfInk()) {pen = penerator.create();}pen.write(data);}
}

在OO Python中

class Pen(metaclass=ABCMeta):def write(self, text):passdef out_of_ink(self):passclass PenFactory(metaclass=ABCMeta):def create(self):passclass Scientist():def __init__(self, pen_factory):self.penerator = pen_factoryself.pen = self.penerator.create()def write_data(self, data):if self.pen.out_of_ink():pen = self.penerator.create()pen.write(data)

您是否了解我如何称呼PenFactory实例penerator ? 我觉得这很傻。 希望您也喜欢。 如果没有,哦。

转换为简单的功能模式

当涉及到Java版本时,由于PenFactory算作功能接口,因此实际上不需要进行任何更改,但是由于您可以用Supplier<Pen>替换PenFactory任何实例,因此PenFactory 。 因此, Scientist类看起来像这样:

public class Scientist {private Supplier penerator;private Pen pen;public Scientist(Supplier penerator) {this.penerator = penerator;this.pen = penerator.get();}public void writeData(String data) {if(pen.outOfInk()) {pen = penerator.get();}pen.write(data);}
}

在Python中,您可以完全删除PenFactory而只需使用返回Pen任何可调用对象即可。 您还必须在“ Scientist中更改调用工厂的create()方法的行,并仅用括号将其替换即可。

class Scientist():def __init__(self, pen_factory):self.penerator = pen_factoryself.pen = self.penerator()def write_report(self, data):if self.pen.out_of_ink():self.pen = self.penerator()self.pen.write(data)

因此,要创建带有提供MyPenClass实例的lambda的Scientist实例,请在Java中键入以下内容:

Scientist albert = new Scientist(() -> new MyPenClass());

或在Python中:

albert = Scientist(lambda: MyPenClass())
# or skip the lambda by passing the "constructor"
thomas = Scientist(MyPenClass)

具有依赖关系的类的工厂

假设我想为一个类的工厂制造工厂,该类的构造函数需要一个笔品牌的名称。 我们将此类BrandPen 。 我们如何为此建立工厂? 好吧,写lambda并没有什么不同,真的。 但是,我们如何看待其他定义传入的可调用对象的方式呢?

在Java中,您可以将lambda的实例保存在变量中并传递给它。或者您可以使用方法引用:

Supplier bicPen = () -> new BrandPen("BiC");
Scientist thomas = new Scientist(bicPen);
// assuming that BrandPen has a static method called bicPen
Scientist nicola = new Scientist(BrandPen::bicPen);

在Python中,您可以定义一个执行该功能的函数或分配一个执行该操作的partial函数:

def bic_pen():return BrandPen("BiC")
# or
bic_pen = partial(BrandPen, "BiC")nicola = Scientist(bic_pen)

有依存关系的工厂

哦,天哪, Scientist现在希望能够指定工厂提供的笔的颜色 ! 好吧,您可以给他提供每种颜色的不同工厂,并告诉他使用每个不同的工厂来制造不同的笔,但是在他的实验室中根本没有足够的空间容纳这么多PenFactory ! 我们必须给工厂提供可以使用哪种颜色的信息。

为此,我们必须将Java的Supplier<Pen>更改为Function<>Color, Pen> 。 显然,您无需在Python中更改类型,因为它是动态的并且不需要类型信息。

但是, Scientist班也需要改变他们使用工厂的方式。 在Java中,无论Scientist在哪里请求新实例,它都需要提供颜色,如下所示:

pen = penerator.apply(Color.RED);

或者像这样,在Python中:

self.pen = self.penerator(Color.RED)

我们传递给Java Scientist的工厂看起来像这样:

Scientist erwin = new Scientist(color -> new ColoredPen(color, "BiC"));

我们在Python中提供的代码可能如下所示:

def colored_bic_pen(color):return ColoredPen(color, "BiC")erwin = Scientist(colored_bic_pen)

多方法工厂

在Internet上“工厂模式”的一些示例中,它们显示了具有多种方法来调用以生成对象的工厂。 我还没有在现实生活中看到这种效果,但是可能会发生。 在这些情况下,最好坚持使用OO选项,但是如果要将其更改为功能模式,只需提供单独的工厂可调用对象,而不是使用多个方法的一个对象即可。

奥托罗

我没想到会写那么多,但是随着我的前进,我想展示太多的变化。 我没有了解所有内容,主要是因为我不想跟踪所有内容,尤其是两种语言,但是我敢肯定,我已经给了您足够好的工具箱,可以在您的网站上找到答案拥有。

我希望你学到了一些东西。 如果没有,我希望您至少喜欢这个例子。

翻译自: https://www.javacodegeeks.com/2015/02/functional-factory-pattern.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360706.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

指向二维数组的指针测试

定义a为二维数组后&#xff0c;有三种成份&#xff1a;数组本身、3个一维数组&#xff08;a的每一行对应一个一维数组&#xff09;、12个数组元素&#xff0c; 由此就有三种指针及对应的指针变量&#xff0c; &a和int &#xff08;*p1&#xff09;&#xff3b;3&#xff3d…

python视频流传输_基于OpenCV的网络实时视频流传输的实现

很多小伙伴都不会在家里或者办公室安装网络摄像头或监视摄像头。但是有时&#xff0c;大家又希望能够随时随地观看视频直播。大多数人会选择使用IP摄像机(Internet协议摄像机)而不是CCTV(闭路电视)&#xff0c;因为它们具有更高的分辨率并降低了布线成本。在本文中&#xff0c;…

如何编写NetBeans插件

是否想在NetBeans IDE中添加功能或自动执行某些操作&#xff1f; 跟随我们编写您的第一个NetBeans插件。 让我们超越简单的工具栏示例 &#xff0c;创建一个可以自动更新的插件。 该代码基于NetBeans的WakaTime插件 。 我们的示例插件将仅打印Hello World语句&#xff0c;并在…

单机最大tcp连接数

单机最大tcp连接数 网络编程 在tcp应用中&#xff0c;server事先在某个固定端口监听&#xff0c;client主动发起连接&#xff0c;经过三路握手后建立tcp连接。那么对单机&#xff0c;其最大并发tcp连接数是多少&#xff1f; 如何标识一个TCP连接 在确定最大连接数之前&#xf…

用了fastapi还需要nginx_nginx 与 fastdfs 的配置过程,已经越过了许多坑,我跪着进入了欢迎页面。。。...

nginx 与 fastdfs 的配置过程&#xff0c;已经越过了许多坑&#xff0c;我跪着进入了欢迎页面。。。上面的是 fastdfs 与 nginx 的官网&#xff0c;我从这里面跌跌撞撞的走出来了&#xff0c;下面是我总结出来的一条平坦的路&#xff0c;小伙伴们可以参考参考。我下面的攻略其实…

Spring Batch教程–最终指南

这是Spring批处理教程&#xff0c;它是Spring框架的一部分。 Spring Batch提供了可重用的功能&#xff0c;这些功能对于处理大量记录至关重要&#xff0c;包括日志记录/跟踪&#xff0c;事务管理&#xff0c;作业处理统计信息&#xff0c;作业重新启动&#xff0c;跳过和资源管…

Neurocomputing 投稿注意事项

1. *.tex 和 *.bib 都以Manuscript项&#xff08;Item&#xff09;提交 &#xff08;abstract.tex除外&#xff09;2. abstract.tex以Abstract项&#xff08;Item&#xff09;提交3. *.eps以Figure项&#xff08;Item&#xff09;提交4. biographies.pdf以Biography of the aut…

箱式图 添加异常值平均值_什么是脏数据?怎样用箱形图分析异常值?终于有人讲明白了...

导读&#xff1a;数据质量分析是数据挖掘中数据准备过程的重要一环&#xff0c;是数据预处理的前提&#xff0c;也是数据挖掘分析结论有效性和准确性的基础。没有可信的数据&#xff0c;数据挖掘构建的模型将是空中楼阁。数据质量分析的主要任务是检查原始数据中是否存在脏数据…

[编程相关]正则表达式Regex语法

--目录-- 0. 前言1. 正则语法2. 正则搜索语法&#xff08;1&#xff09;字符集 Character_Classes&#xff08;2&#xff09;锚定符 Anchors&#xff08;3&#xff09;计数 Quantifiers&#xff08;4&#xff09;分组与索引 Group_And_Reference&#xff08;5&#xff09;周围 …

窗口程序ImageView(仿QQ图片查看器)

近期一直在学习窗口程序之类的问题,下午正好有机会和大家讨论一下. 程序运行截图&#xff1a; 应用方法&#xff1a; 1、直接把图像文件拖到图标上表现 2、通过命令行方式&#xff0c;示例&#xff1a;ImageView.exe "带全路径的图像文件名称" 3、打开ImageView.exe&…

华为硬件工程师社招机考题库_干货:2016年华为中兴硬件工程师笔试题目与经验...

1。一位工科男在拿到华为实习生offer后的面经干货某211学校&#xff0c;机械学院研究生。不得不说一下&#xff0c;华为的员工们真的是认真做事&#xff0c;因为怕我们担心下班轮不到面试。工作人员特意去休息区告诉我们&#xff0c;不面试完他们不会下班&#xff0c;果然是个爱…

USACO3.15stamps(dp)

对dp很无奈。。枚举所有可能达到的值 dp[i]表示到达i值所用最少的邮票 1 /*2 ID: shangca23 LANG: C4 TASK: stamps5 */6 #include <iostream>7 #include<cstdio>8 #include<cstring>9 #include<stdlib.h> 10 #include<algorithm> …

thinkcmf搭建教程_5分钟快速入门

# 5分钟快速入门[TOC1,5]## 1.创建模板目录在public/themes/目录下创建quick_start目录## 2.添加模板描述文件在public/themes/quick_start目录下创建manifest.json文件&#xff0c;内容如下&#xff1a;{"name": "quick_start","version": &quo…

WAV格式

查看下面文章时,请用记事本打开一个wav格式的文件. WAV格式是微软公司开发的一种声音文件格式&#xff0c;也叫波形声音文件&#xff0c;是最早的数字音频格式&#xff0c;被Windows平台及其应用程序广泛支持。WAV格式支持许多压缩算法&#xff0c;支持多种音频位数、采样频率和…

基于价值的类

在Java 8中&#xff0c;某些类在Javadoc中有一个小注释&#xff0c;说明它们是基于值的类 。 其中包括简短说明的链接&#xff0c;以及有关不使用它们的限制。 这很容易被忽略&#xff0c;如果这样做&#xff0c;则可能会在将来的Java版本中以微妙的方式破坏代码。 为了避免这种…

angular五大服务顺序,angularJS $事件处理程序的触发顺序

I was wondering two things, in the context of angularJS event handling.How is defined the order in which handlers listening to the same event are triggered?Is it a sign of a bad design if you start wondering about this?After reading documentation on angu…

地形 凹陷

地形凹下去&#xff1a;先要设置terrain-flattenheightmap 这个 转载于:https://www.cnblogs.com/wolfsky6/archive/2013/05/29/3106078.html

REST API的演变

每个开发人员都以某种方式接触到API 。 要么为一家大公司集成一个主要系统&#xff0c;或者使用最新的图形库生成一些精美的图表&#xff0c;要么直接与他喜欢的编程语言进行交互。 事实是&#xff0c;API无处不在&#xff01; 它们实际上代表了当今Internet的基本构建块&#…

python爬携程酒店评论_python爬虫爬取携程网的酒店评论数据时,有个请求参数不知道是怎么生成的?...

是下面这个代码生成的&#xff0c;看不懂&#xff1a;,_getElevenValue:function(e){function o(e){for(var o["A","B","C","D","E","F","G","H","I","J","K"…

Oracle MAF中的LOV

我们都喜欢最强大的ADF功能值列表之一。 使用它们&#xff0c;我们可以在ADF应用程序中声明性地轻松构建非常复杂的功能。 一件好事是&#xff0c;我们在Oracle MAF中也有类似的方法。 在ADF BC中&#xff0c;我们在业务服务级别&#xff08;基本上在实体或VO级别&#xff09;定…