功能工厂模式
您是否需要一種非常快速的方法來制作Factory對象? 然后,您需要lambda或其他函數傳遞! 它不僅快速,而且非常簡單。 我敢打賭,如果您對Lambdas相當滿意,那么您只需閱讀標題就可以做到這一點。 如果您是其中之一,請堅持; 你永遠不知道你能學到什么。
附帶說明:我正在用Java和Python編寫代碼示例。 為什么? 因為我喜歡這兩種語言,所以為這兩種語言放東西肯定不會造成傷害。
工廠模式入門
如果您已經知道什么是工廠設計模式,則可以跳到下一部分。
Factory模式的重點是為對象和方法提供一種實例化對象的方式,而無需暴露所有(或通常是任何一種 )實例化邏輯(需要將哪些內容傳遞給構造函數)。
例
舉一個愚蠢的例子,假設有一類“ Scientist ,它需要一種方法來產生新的Pen來寫下實驗數據,但是他不想被創建過程所困擾。 為此,您將為Scientist一個PenFactory , Scientist只需知道按一下工廠上的按鈕即可獲得新的筆。
PenFactory是一個簡單的對象,只有一個create()方法,可在每次調用它時提供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):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
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
- 上一篇: (联通云盾ddos可以几级清洗)
- 下一篇: 如何编写NetBeans插件