功能工厂模式

您是否需要一种非常快速的方法来制作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):
        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算作功能接口,因此实际上不需要进行任何更改,但是由于您可以用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_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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值