电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

JAVA中用動態(tài)代理類實現(xiàn)記憶功能(一)

瀏覽:11日期:2024-06-22 18:52:51
內(nèi)容: 記憶是衍生自Lisp,Python,和Perl等過程性語言的一種設(shè)計模式,它可以對前次的計算結(jié)果進行記憶。 一個實現(xiàn)了記憶功能的函數(shù), 帶有顯式的cache, 所以, 已經(jīng)計算過的結(jié)果就能直接從cache中獲得, 而不用每次都進行計算.記憶能顯著的提升大計算量代碼的效率. 而且是一種可重用的方案.本文闡述了在Java中使用這一模式的方法,并提供了一個可以提供上述功能的'記憶類': Foo foo = (Foo) Memoizer.memoize(new FooImpl()); 這里,Foo是一個接口,它含有的方法是需要記憶的.FooImpl是Foo的一個實現(xiàn).foo是Foo的一個引用.方法與FooImpl基本相同,區(qū)別在于Foo返回的值,會被緩存起來.單個記憶類的優(yōu)點在于為任何類添加記憶功能是很簡單的:定義一個包含需要記憶的方法的接口,然后調(diào)用memoize來實現(xiàn)一個實例. 為了理解記憶類是怎么實現(xiàn)的,我們將分幾步來解釋.首先,我解釋一下為何緩存能夠在需要它的類中實現(xiàn).然后,我測試一下如何為一個特定的類添加緩存包裝器.最后,我解釋一下如何才能使得一個緩存包裝器能夠通用于任意的類.為大計算量的程序添加緩存 作為一個大計算量程序的例子,我們考慮PiBinaryDigitsCalculator這個例子-計算二進制數(shù)據(jù)pi.僅有的public方法calculateBinaryDigit帶有一個參數(shù):整數(shù)n,代表需要精確到的位數(shù).例如,1000000,將會返回小數(shù)點后的一百萬位,通過byte值返回-每位為0或者1.(算法可以參考: http://www.cecm.sfu.ca/~pborwein/PAPERS/P123.pdf)public class PiBinaryDigitsCalculator { /** * Returns the coefficient of 2^n in the binary * expansion of pi. * @param n the binary digit of pi to calculate. * @throws ValidityCheckFailedException if the validity * check fails, this means the implementation is buggy * or n is too large for sufficient precision to be * retained. */ public byte calculateBinaryDigit(final int n) { return runBBPAlgorithm(n); } private byte runBBPAlgorithm(final int n) { // Lengthy routine goes here ... }} 最簡單直接的方法來緩存返回值可以通過修改這個類來實現(xiàn):添加一個Map來保存之前計算得到的值,如下:import java.util.HashMap;public class PiBinaryDigitsCalculator { private HashMap cache = new HashMap(); public synchronized byte calculateBinaryDigit( final int n) { final Integer N = new Integer(n); Byte B = (Byte) cache.get(N); if (B == null) { byte b = runBBPAlgorithm(n); cache.put(N, new Byte(b)); return b; } else { return B.byteValue(); } } private byte runBBPAlgorithm(final int n) { // Lengthy routine goes here ... }} calculateBinaryDigit方法首先會檢查HashMap里面是否緩存了這個關(guān)鍵字-參數(shù)n,如果找到了,就直接返回這個值.否則,就會進行這個冗長的計算,并將結(jié)果保存到緩存里面.在添加進HashMap的時候,在原始類型和對象之間還要進行小小的轉(zhuǎn)換. 盡管這個方法是可行的,但是有幾個缺點.首先,進行緩存的代碼和正常的算法代碼不是顯著分開的.一個類,不僅負(fù)責(zé)進行計算,也要負(fù)責(zé)進行維護緩存數(shù)據(jù).這樣,要進行一些測試就會顯得很困難.比如,不能寫一個測試程序來測試這個算法持續(xù)地返回相同的值,因為,從第二次開始,結(jié)果都是直接從cache中獲得了. 其次,當(dāng)緩存代碼不再需要,移除它會變得困難,因為它和算法塊地代碼是緊密結(jié)合在一起的.所以,要想知道緩存是否帶來了很高的效率提升也是很困難的,因為不能寫一個測試程序是和緩存數(shù)據(jù)分開的.當(dāng)你改進了你的算法,緩存有可能失效-但是這個時候你并不知道. 第三,緩存代碼不能被重用.盡管代碼遵從了一個普通的模式,但是都是在一個類- PiBinaryDigitsCalculator里面. 前面兩個問題都可以通過構(gòu)造一個緩存包裝器來解決.緩存包裝器 通過使用Decorator模式,要分開計算代碼和緩存代碼是很容易的.首先,定義一個接口,里面定義基本的方法. public interface BinaryDigitsCalculator { public byte calculateBinaryDigit(final int n);} 然后定義兩個實現(xiàn),分別負(fù)責(zé)兩個任務(wù):public class PiBinaryDigitsCalculator implements BinaryDigitsCalculator { public byte calculateBinaryDigit(final int n) { return runBBPAlgorithm(n); } private byte runBBPAlgorithm(final int n) { // Lengthy routine goes here ... }}import java.util.HashMap;public class CachingBinaryDigitsCalculator implementsBinaryDigitsCalculator { private BinaryDigitsCalculator binaryDigitsCalculator; private HashMap cache = new HashMap(); public CachingBinaryDigitsCalculator( BinaryDigitsCalculator calculator) { this.binaryDigitsCalculator = calculator; } public synchronized byte calculateBinaryDigit(int n) { final Integer N = new Integer(n); Byte B = (Byte) cache.get(N); if (B == null) { byte b = binaryDigitsCalculator.calculateBinaryDigit(n); cache.put(N, new Byte(b)); return b; } else { return B.byteValue(); } }} 這是很之前的實現(xiàn)PiBinaryDigitsCalculator的一種簡單的refactored版本. CachingBinaryDigitsCalculator包裝了BinaryDigitsCalculator句柄,并增加了緩存,供calculateBinaryDigit的方法調(diào)用. 這種方法提高了代碼的可讀性與可維護性. 用戶不能直接使用BinaryDigitsCalculator接口來實現(xiàn)算法,所以,如果需要關(guān)閉緩存塊,將是很容易實現(xiàn)的. 還有,合適的測試程序很容易寫出來.比如,我們寫一個假的BinaryDigitsCalculator實現(xiàn),每次calculateBinaryDigit被調(diào)用,賦予相同的參數(shù),返回不同的值. 這樣,我們就能測試緩存是否工作了,因為如果每次都返回相同的值,則證明緩存是正常工作了. 這種測試在之前那種簡單的實現(xiàn)是不可能的.關(guān)于翻譯作者chris,熱衷于java游戲引擎技術(shù),jvm技術(shù),活躍于jxta社區(qū).可以點擊:http://www.matrix.org.cn/user_view.asp?username=chris查看他的個人信息 Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 拉力机-拉力试验机-万能试验机-电子拉力机-拉伸试验机-剥离强度试验机-苏州皖仪实验仪器有限公司 | 澳洁干洗店加盟-洗衣店干洗连锁「澳洁干洗免费一对一贴心服务」 干洗加盟网-洗衣店品牌排行-干洗设备价格-干洗连锁加盟指南 | 考勤系统_考勤管理系统_网络考勤软件_政企|集团|工厂复杂考勤工时统计排班管理系统_天时考勤 | 定制奶茶纸杯_定制豆浆杯_广东纸杯厂_[绿保佳]一家专业生产纸杯碗的厂家 | 蒸压釜-陶粒板隔墙板蒸压釜-山东鑫泰鑫智能装备有限公司 | 3d可视化建模_三维展示_产品3d互动数字营销_三维动画制作_3D虚拟商城 【商迪3D】三维展示服务商 广东健伦体育发展有限公司-体育工程配套及销售运动器材的体育用品服务商 | POM塑料_PBT材料「进口」聚甲醛POM杜邦原料、加纤PBT塑料报价格找利隆塑料 | 农业仪器网 - 中国自动化农业仪器信息交流平台 | 分子精馏/精馏设备生产厂家-分子蒸馏工艺实验-新诺舜尧(天津)化工设备有限公司 | 防水套管|柔性防水套管|伸缩器|伸缩接头|传力接头-河南伟创管道 防水套管_柔性防水套管_刚性防水套管-巩义市润达管道设备制造有限公司 | 浙江上沪阀门有限公司 | 灌木树苗-绿化苗木-常绿乔木-价格/批发/基地 - 四川成都途美园林 | 杭州门窗厂家_阳光房_包阳台安装电话-杭州窗猫铝合金门窗 | 哲力实业_专注汽车涂料汽车漆研发生产_汽车漆|修补油漆品牌厂家 长沙一级消防工程公司_智能化弱电_机电安装_亮化工程专业施工承包_湖南公共安全工程有限公司 | 雷达液位计_超声波风速风向仪_雨量传感器_辐射传感器-山东风途物联网 | 浙江美尔凯特智能厨卫股份有限公司| 【铜排折弯机,钢丝折弯成型机,汽车发泡钢丝折弯机,线材折弯机厂家,线材成型机,铁线折弯机】贝朗折弯机厂家_东莞市贝朗自动化设备有限公司 | 深圳天际源广告-形象堆头,企业文化墙,喷绘,门头招牌设计制作专家 | 医疗仪器模块 健康一体机 多参数监护仪 智慧医疗仪器方案定制 血氧监护 心电监护 -朗锐慧康 | 微型气象仪_气象传感器_防爆气象传感器-天合传感器大全 | 聚氨酯催化剂K15,延迟催化剂SA-1,叔胺延迟催化剂,DBU,二甲基哌嗪,催化剂TMR-2,-聚氨酯催化剂生产厂家 | 诸城网站建设-网络推广-网站优化-阿里巴巴托管-诸城恒泰互联 | 热风机_工业热风机生产厂家上海冠顶公司提供专业热风机图片价格实惠 | 内窥镜-工业内窥镜厂家【上海修远仪器仪表有限公司】 | 翰墨AI智能写作助手官网_人工智能问答在线AI写作免费一键生成 | 钢衬玻璃厂家,钢衬玻璃管道 -山东东兴扬防腐设备有限公司 | 台湾Apex减速机_APEX行星减速机_台湾精锐减速机厂家代理【现货】-杭州摩森机电 | 打包箱房_集成房屋-山东佳一集成房屋有限公司| 不锈钢水箱生产厂家_消防水箱生产厂家-河南联固供水设备有限公司 | 船用烟火信号弹-CCS防汛救生圈-船用救生抛绳器(海威救生设备) | 锂离子电池厂家-山东中信迪生电源 | 深圳市简易检测技术有限公司 | 旅游规划_旅游策划_乡村旅游规划_景区规划设计_旅游规划设计公司-北京绿道联合旅游规划设计有限公司 | 大米加工设备|大米加工机械|碾米成套设备|大米加工成套设备-河南成立粮油机械有限公司 | 北京开业庆典策划-年会活动策划公司-舞龙舞狮团大鼓表演-北京盛乾龙狮鼓乐礼仪庆典策划公司 | 软瓷_柔性面砖_软瓷砖_柔性石材_MCM软瓷厂家_湖北博悦佳软瓷 | 顺辉瓷砖-大国品牌-中国顺辉 | 代做标书-代写标书-专业标书文件编辑-「深圳卓越创兴公司」 | 考试试题_试卷及答案_诗词单词成语 - 优易学 | 隆众资讯-首页_大宗商品资讯_价格走势_市场行情 | 120kv/2mA直流高压发生器-60kv/2mA-30kva/50kv工频耐压试验装置-旭明电工 |