![工厂模式功能说明](https://i-blog.csdnimg.cn/blog_migrate/1e43bc14df038b239572e5a00fb8407f.png)
工厂模式功能说明
您是否需要一种非常快速的方法来制作Factory对象? 然后,您需要lambda或其他函数传递! 它不仅快速,而且非常简单。 我敢打赌,如果您对Lambdas非常满意,那么您只需阅读标题就可以做到这一点。 如果您是其中之一,请坚持; 你永远不知道你能学到什么。
附带说明:我正在用Java和Python做代码示例。 为什么? 因为我喜欢这两种语言,所以为这两种语言放东西肯定不会造成伤害。
工厂模式入门
如果您已经知道什么是工厂设计模式,则可以跳至下一部分。
Factory模式的重点是为对象和方法提供一种实例化对象的方法,而无需暴露所有(或通常是任何一种)实例化逻辑(需要将什么传递给构造函数)。
例
举一个愚蠢的例子,假设有一类“ Scientist
,它需要一种方法来产生新的Pen
来写下实验数据,但是他不想被创建过程所困扰。 为此,您将为Scientist
一个PenFactory
, Scientist
只需知道按一下工厂上的按钮即可获得新的笔。
PenFactory
是一个简单的对象,只有一个create()
方法,该方法在您每次调用Pen
时都会提供一个新的Pen
实例。 如果Scientist
关心Pen
颜色,则可以为他提供ColoredPenFactory
, ColoredPenFactory
的create()
方法也接受颜色参数。 然后, 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):
pass
def out_of_ink(self):
pass
class PenFactory(metaclass=ABCMeta):
def create(self):
pass
class Scientist():
def __init__(self, pen_factory):
self.penerator = pen_factory
self.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
算作功能接口,因此实际上不需要进行任何更改,但是由于您可以将任何PenFactory
实例PenFactory
为Supplier<Pen>
,因此不需要它。 因此, 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_factory
self.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
工厂模式功能说明