[翻译] 理解贷出模式 Loan Pattern

Loan Pattern as the name suggests would loan a resource to your function. So if you break out the sentence. It would

  • Create a resource which you can use
  • Loan the resources to the function which would use it
  • This function would be passed by the caller
  • The resource would be destroyed

就像名字所说的一样,贷出模式(Loan Pattern)会借贷出一个资源给予你的函数。它可以  1.创建一个你可以使用的资源  2.载入这个资源到你的函数中让你使用  3.函数由调用者提供  4.资源会被摧毁回收

As you would see, the advantages are multifold. First, I am not constrained by the function which can use the loaned resource. I can pass any function that I desire. Second, I am not concerned about the creation, destruction of the resource. The loan function takes care of it.

就像你即将看到的一样,贷出模式的优势有很多。首先我不会受到使用资源的函数的限制。我可以传入我希望的任何函数。 第二个优势是我不用担心资源的创建和回收。贷出函数会自己处理这些。

Let us take an example, we have all used connections to get to the database and then we need to destroy the connection so that there are no leaks. OK, we can use the connection factory but let us assume that we do not have that for now. The general code would look like this

让我们举一个例子,我们都使用过数据库连接并用它连接数据库,再回收数据库连接以确保没有资源泄露。当然,我们可以使用数据库连接的工厂类,但是假设我们现在没有工厂类。那么代码就大概像下面这样。

def doSqlCall = {
  varconn:Connection = null
  try{
    valurl = "jdbc:mysql://localhost:3306/"
    Class.forName("com.mysql.jdbc.Driver").newInstance()
    conn = DriverManager.getConnection(url + "vikas","userName","password")
    valstmt = conn.prepareStatement("insert into employee (id,age) values (?,?) ")
    stmt.setString(1,"1001")
    stmt.setInt(2,"21")
    stmt.executeUpdate()
  }catch{
    caseex:Exception => {
      println("Exception: " + ex.getMessage)
    }
  }finally{
    conn.close
  }
}

As you would notice that the code snippet can be improved for confirming to the functional standards but that is not the motive right now. If you notice, apart from all the boilerplating or all the work that needs to be done, a few lines are all that change everytime this function is called.

你会注意到这段代码中大部分代码都是用来建立或回收数据库连接,类似于一个“模板”,只有一小段代码是有可能发生变化的,就是下面这一段。

valstmt = conn.prepareStatement("insert into employee (id,age) values (?,?) ")
stmt.setString(1,"1001")
stmt.setInt(2,"21")
stmt.executeUpdate()

What if we could pass these 4 lines to the function above and still be able to use the boilerplating. The loan pattern attempts to provide exactly that. You would need to pass the functionality and not worry about the resources.

如果我们把这四句代码放入一个函数,并且仍然可以使用那个创建/回收数据库连接的“模板”,那感觉如何呢?这就是贷出模式要做的。你只需要传入一个自定义函数(类似于上面这四句代码),而不需要担心资源的创建和回收。

Let us pull the code that we want to execute into a method of its own

让我们把我们希望执行的代码(上面四句)提取出来放入一个单独的函数

def executeMySqlFunction(conn:Connection):Int = {
  valstmt = conn.prepareStatement("insert into employee (id,age) values (?,?) ")
  stmt.setString(1,"1001")
  stmt.setInt(2,"21")
  stmt.executeUpdate()
}

You would see that this method takes connection (which is the resource which would be loaned) as an argument and returns integer.

你回看到这个方法需要数据库连接(会被使用的资源)作为参数,并返回一个整型值

Now let us look at the base method

def doLoanSqlCall(f:Connection => Int) = {
  varconn:Connection =null
  try{
    valurl = "jdbc:mysql://localhost:3306/"
    Class.forName("com.mysql.jdbc.Driver").newInstance()
    conn = DriverManager.getConnection(url + "vikas","userName","password")

    f(conn)

  }catch{
    caseex:Exception => {
      println("Exception: " + ex.getMessage)
    }
  }finally{
    conn.close
  }
}

Here, we have defined the doLoanSqlCall as a method, which would take another function as an argument. Thus, doLoanSqlCall becomes a higher order function. The function which is taken as an argument should take a connection as an argument and return Int. If you look at the definition of

这里,我们已经定义了一个函数 doLoadSqlCall(),它会将另一个函数(我们就称它为用户函数)作为参数。因此,doLoadSqlCall()变成了一个更高阶的函数。作为参数的函数(用户函数)应该将数据库连接作为参数,并返回一个整型值。如果你看下用户函数的定义:

def executeMySqlFunction(conn:Connection):Int

it does exactly that. Takes connection as the argument and returns an Int. The only thing that executeMySqlFunction does not have to worry about is that how would be create the connection and whether it needs to destroy the connection when it is done. The connection resource is loaned by the other method.

Hence the call becomes

doLoanSqlCall(executeMySqlFunction)

and this is now valid for any other SQL function which follows the format connection=>Int

感受与总结:贷出模式就是一个将需要系统资源执行的操作抽象的模式。本来的逻辑是:1. 创建系统资源  2.执行用户需要的逻辑  3.回收系统资源。但是如果使用了贷出模式,那么就被抽象成为了两个函数:1)用户函数 和 2)贷出函数。用户函数作为参数传入给贷出函数。调用者需要调用的是 贷出函数。

1)用户函数(user_function)中定义了用户自己希望执行的操作(这些操作需要使用系统资源)。由于这些操作需要使用系统资源,那么资源会作为用户函数的参数传入,以提供给用户使用。

2)贷出函数(load_function)中则定义了系统资源的获取与回收,并且在获取资源之后,回收资源之前,调用用户函数(将系统资源作为参数传入)。

结构类似于:

load_function(user_function) { allocate resource user_function(resource) release resource}

终端用户需要直接调用的是贷出函数。

时间: 2024-08-25 20:35:15

[翻译] 理解贷出模式 Loan Pattern的相关文章

用最简单的例子理解装饰器模式(Decorator Pattern)

假设有一个公司要做产品套餐,即把不同的产品组合在一起,不同的组合对应不同的价格.最终呈现出来的效果是:把产品组合的所有元素呈现出来,并显示该组合的价格. 每个产品都有名称和价格,首先设计一个关于产品的抽象基类. public abstract class ProductBase { public abstract string GetName(); public abstract double GetPrice(); } 所有的产品都必须继承这个基类,比如家居用品.电器产品等,把这些具体的产品提

菜鸟理解的工厂模式(Factory Pattern)是什么样子的?

直接开始说了,不浪费园友宝贵的时间! 什么是工厂模式? 在学习前,先问一下:"它是什么?". 工厂模式,它是项目里面常用的设计模式之一. 它是属于创建型模式,简单的理解创建型模式就是将实例化工作交给另外一个对象来完成. 工厂模式(又称静态工厂模式 Static Factory Method),它算是软件设计模式中最简单的模式了. 为了解决什么问题? 工厂模式使代码清晰,降低耦合度,调用者通过 接口/抽象类来获得想要的实例化,而无需关心细节上是如何实现的. 工厂模式是一种典型的解耦模式,

设计模式(结构型)之享元模式(Flyweight Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(结构型)之外观模式(Facade Pattern)>http://blog.csdn.net/yanbober/article/details/45476527 概述 当一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题.所以需要采用一

[Java 8] (9) Lambda表达式对递归的优化(下) - 使用备忘录模式(Memoization Pattern) .

使用备忘录模式(Memoization Pattern)提高性能 这个模式说白了,就是将需要进行大量计算的结果缓存起来,然后在下次需要的时候直接取得就好了.因此,底层只需要使用一个Map就够了. 但是需要注意的是,只有一组参数对应得到的是同一个值时,该模式才有用武之地. 在很多算法中,典型的比如分治法,动态规划(Dynamic Programming)等算法中,这个模式运用的十分广泛. 以动态规划来说,动态规划在求最优解的过程中,会将原有任务分解成若干个子任务,而这些子任务势必还会将自身分解成更

例说装饰者模式(Decorator Pattern)

前言 装饰者模式在餐饮行业有着比较广泛的应用,网上大部分关于该模式的例子都和饮食相关,以前看译制片电影,每当看到老外们在咖啡店一口流利的点咖啡要加糖要加奶昔要加这加那的时候,感觉好有派~好高大上啊~,为啥我在小卖部都是"来瓶汽水"就没话说了呢~,难道是我不会"装"? 官方定义 动态的给一个对象添加一些职责,就增加功能来说,该模式比生成子类更为灵活--GOF Decorator模式是一种相对简单的对象结构性模式,动态和对象是个对应的关系,正如静态和类这样的对应关系,编

[Java 8] Lambda表达式对递归的优化(下) - 使用备忘录模式(Memoization Pattern)

使用备忘录模式(Memoization Pattern)提高性能 这个模式说白了,就是将需要进行大量计算的结果缓存起来,然后在下次需要的时候直接取得就好了.因此,底层只需要使用一个Map就够了. 但是需要注意的是,只有一组参数对应得到的是同一个值时,该模式才有用武之地. 在很多算法中,典型的比如分治法,动态规划(Dynamic Programming)等算法中,这个模式运用的十分广泛. 以动态规划来说,动态规划在求最优解的过程中,会将原有任务分解成若干个子任务,而这些子任务势必还会将自身分解成更

【设计模式】桥接模式 Bridge Pattern

开篇还是引用吕振宇老师的那篇经典的文章<设计模式随笔-蜡笔与毛笔的故事>.这个真是太经典了,没有比这个例子能更好的阐明桥接模式了,这里我就直接盗来用了. 现在市面上卖的蜡笔很多,各种型号,各种颜色种类繁多, 假如一盒蜡笔有24种颜色,那么它能涂抹出24种不同的颜色来,蜡笔型号是固定的,如果想画出各种线条那么就要购买不同型号的蜡笔,假如我们要涂抹出粗,中,细三种线条,那么我们就要买3盒粗,中,细型号的蜡笔才能满足需求,那么就是3盒*24色=72只蜡笔.假如使用毛笔来作画,我们需要准备3只粗,中,

设计模式之七:建造模式(Builder Pattern)

建造者模式就是将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示. 适用范围: 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时. 当构造过程必须允许被构造的对象有不同表示时. 建造者模式里面有四个角色: Builder: 给出一个抽象接口,以规范产品对象的各个组成部分的建造.一般而言,此接口独立于应用程序的业务逻辑.模式中直接创建产品对象的具体创建者角色.具体创建者角色必须实现这个接口的所有方法:一个是建造方法,另一个是结果返还方法. ConcreteBu

规约模式(Specification Pattern)

前期准备之规约模式(Specification Pattern) 一.前言 在专题二中已经应用DDD和SOA的思想简单构建了一个网上书店的网站,接下来的专题中将会对该网站补充更多的DDD的内容.本专题作为一个准备专题,因为在后面一个专题中将会网上书店中的仓储实现引入规约模式.本专题将详细介绍了规约模式. 二.什么是规约模式 讲到规约模式,自然想到的是什么是规约模式呢?从名字上看,规约模式就是一个约束条件,我们在使用仓储进行查询的时候,这时候就会牵涉到很多查询条件,例如名字包含C#的书名等条件.这