[{"data":1,"prerenderedAt":922},["ShallowReactive",2],{"i-simple-icons:github":3,"i-simple-icons:x":8,"i-brand:linkedin":10,"i-simple-icons:medium":14,"i-lucide:mail":16,"i-lucide:sun":18,"pattern:\u002Flearn\u002Fdesign-patterns\u002Fproxy":20,"pattern-group:\u002Flearn\u002Fdesign-patterns\u002Fproxy":870,"i-lucide:lightbulb":902,"i-lucide:boxes":904,"i-lucide:plug":906,"i-lucide:bridge":908,"i-lucide:network":910,"i-lucide:gift":912,"i-lucide:door-open":914,"i-lucide:feather":916,"i-lucide:shield-check":918,"i-lucide:copy":920},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":4,"top":11,"width":12,"height":12,"rotate":4,"vFlip":6,"hFlip":6,"body":13},32,448,"\u003Cpath fill=\"currentColor\" d=\"M416 32L31.9 32C14.3 32 0 46.5 0 64.3L0 447.7C0 465.5 14.3 480 31.9 480L416 480c17.6 0 32-14.5 32-32.3l0-383.4C448 46.5 433.6 32 416 32zM135.4 416l-66.4 0 0-213.8 66.5 0 0 213.8-.1 0zM102.2 96a38.5 38.5 0 1 1 0 77 38.5 38.5 0 1 1 0-77zM384.3 416l-66.4 0 0-104c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9l0 105.8-66.4 0 0-213.8 63.7 0 0 29.2 .9 0c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9l0 117.2z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cpath fill=\"currentColor\" d=\"M4.21 0A4.2 4.2 0 0 0 0 4.21v15.58A4.2 4.2 0 0 0 4.21 24h15.58A4.2 4.2 0 0 0 24 19.79v-1.093a5 5 0 0 1-.422.02c-2.577 0-4.027-2.146-4.09-4.832a8 8 0 0 1 .022-.708c.093-1.186.475-2.241 1.105-3.022a3.9 3.9 0 0 1 1.395-1.1c.468-.237 1.127-.367 1.664-.367h.023q.151 0 .303.01V4.211A4.2 4.2 0 0 0 19.79 0Zm.198 5.583h4.165l3.588 8.435l3.59-8.435h3.864v.146l-.019.004c-.705.16-1.063.397-1.063 1.254h-.003l.003 10.274c.06.676.424.885 1.063 1.03l.02.004v.145h-4.923v-.145l.019-.005c.639-.144.994-.353 1.054-1.03V7.267l-4.745 11.15h-.261L6.15 7.569v9.445c0 .857.358 1.094 1.063 1.253l.02.004v.147H4.405v-.147l.019-.004c.705-.16 1.065-.397 1.065-1.253V6.987c0-.857-.358-1.094-1.064-1.254l-.018-.004zm19.25 3.668c-1.086.023-1.733 1.323-1.813 3.124H24V9.298a1.4 1.4 0 0 0-.342-.047m-1.862 3.632c-.1 1.756.86 3.239 2.204 3.634v-3.634z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m22 7l-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"id":21,"title":22,"body":23,"description":856,"example":857,"extension":858,"group":859,"icon":860,"meta":861,"navigation":215,"order":255,"path":862,"rawbody":863,"seo":864,"sitemap":865,"source":866,"stem":867,"summary":868,"__hash__":869},"patterns\u002Flearn\u002Fdesign-patterns\u002Fproxy.md","Proxy",{"type":24,"value":25,"toc":846},"minimark",[26,31,35,38,41,45,61,65,70,81,85,93,97,105,163,167,259,433,720,828,834,842],[27,28,30],"h2",{"id":29},"the-idea","The idea",[32,33,34],"p",{},"Sometimes you want to control access to an object without changing it or its callers. The object may be expensive to create, it may live on another machine, or only some callers may be allowed to use it.",[32,36,37],{},"A proxy is a stand-in with the same interface as the real object. Callers use the proxy as if it were the real thing. The proxy holds a reference to the real object and decides when to create it, whether to let a call through, and what to do before or after passing it on.",[32,39,40],{},"The Gang of Four name a few kinds. A virtual proxy creates the real object only when it is first needed. A protection proxy checks whether a call is allowed. A remote proxy stands in for an object that lives somewhere else, such as on a server.",[27,42,44],{"id":43},"when-to-use-it","When to use it",[46,47,48,52,55,58],"ul",{},[49,50,51],"li",{},"The real object is expensive to create, and you want to wait until it is used.",[49,53,54],{},"You want to check permissions or state before a call reaches the real object.",[49,56,57],{},"The real object lives on another machine, and callers shouldn't have to deal with the network.",[49,59,60],{},"You want to add logging, caching or call counting without touching the real class.",[27,62,64],{"id":63},"pros-and-cons","Pros and cons",[66,67,69],"h3",{"id":68},"pros","Pros",[46,71,72,75,78],{},[49,73,74],{},"It controls access to an object without the object or its callers changing.",[49,76,77],{},"It can stand in for a remote object, so callers treat it as a local one.",[49,79,80],{},"It can create the real object late, or not at all if it is never used.",[66,82,84],{"id":83},"cons","Cons",[46,86,87,90],{},[49,88,89],{},"It adds a layer between the caller and the real object, which can slow responses down.",[49,91,92],{},"It adds a class, and the proxy must follow every change to the interface.",[27,94,96],{"id":95},"the-example","The example",[32,98,99,100,104],{},"The example wraps a database. The proxy creates the real database only when ",[101,102,103],"code",{},"connect()"," is called, and refuses queries while it is not connected.",[46,106,107,128,136,150],{},[49,108,109,115,116,119,120,123,124,127],{},[110,111,112],"strong",{},[101,113,114],{},"Database",": the subject interface shared by the proxy and the real object: ",[101,117,118],{},"connect",", ",[101,121,122],{},"disconnect"," and ",[101,125,126],{},"executeQuery",".",[49,129,130,135],{},[110,131,132],{},[101,133,134],{},"RealDatabase",": the real subject, which does the actual work.",[49,137,138,143,144,146,147,149],{},[110,139,140],{},[101,141,142],{},"DatabaseProxy",": the proxy. It creates a ",[101,145,134],{}," in ",[101,148,103],{},", not before, and keeps track of whether it is connected. It passes queries through only while connected, and prints a message otherwise.",[49,151,152,157,158,160,161,127],{},[110,153,154],{},[101,155,156],{},"Demo",": the client. It holds the proxy as a ",[101,159,114],{}," and never sees ",[101,162,134],{},[27,164,166],{"id":165},"the-code","The code",[168,169,175],"pre",{"className":170,"code":171,"filename":172,"language":173,"meta":174,"style":174},"language-java shiki shiki-themes haytham-dark haytham-light","public interface Database {\n    void connect();\n\n    void disconnect();\n\n    void executeQuery(String query);\n}\n","Database.java","java","",[101,176,177,197,210,217,227,232,253],{"__ignoreMap":174},[178,179,182,186,189,193],"span",{"class":180,"line":181},"line",1,[178,183,185],{"class":184},"sVsk0","public",[178,187,188],{"class":184}," interface",[178,190,192],{"class":191},"sNwy7"," Database",[178,194,196],{"class":195},"sVG6I"," {\n",[178,198,200,203,207],{"class":180,"line":199},2,[178,201,202],{"class":184},"    void",[178,204,206],{"class":205},"sVz7n"," connect",[178,208,209],{"class":195},"();\n",[178,211,213],{"class":180,"line":212},3,[178,214,216],{"emptyLinePlaceholder":215},true,"\n",[178,218,220,222,225],{"class":180,"line":219},4,[178,221,202],{"class":184},[178,223,224],{"class":205}," disconnect",[178,226,209],{"class":195},[178,228,230],{"class":180,"line":229},5,[178,231,216],{"emptyLinePlaceholder":215},[178,233,235,237,240,243,246,250],{"class":180,"line":234},6,[178,236,202],{"class":184},[178,238,239],{"class":205}," executeQuery",[178,241,242],{"class":195},"(",[178,244,245],{"class":184},"String",[178,247,249],{"class":248},"sWFPS"," query",[178,251,252],{"class":195},");\n",[178,254,256],{"class":180,"line":255},7,[178,257,258],{"class":195},"}\n",[168,260,263],{"className":170,"code":261,"filename":262,"language":173,"meta":174,"style":174},"public class RealDatabase implements Database {\n    public void connect() {\n        System.out.println(\"Connecting to real database...\");\n    }\n\n    public void disconnect() {\n        System.out.println(\"Disconnecting from real database...\");\n    }\n\n    public void executeQuery(String query) {\n        System.out.println(\"Executing query: \" + query + \" on real database\");\n    }\n}\n","RealDatabase.java",[101,264,265,282,297,321,326,330,342,361,366,371,391,423,428],{"__ignoreMap":174},[178,266,267,269,272,275,278,280],{"class":180,"line":181},[178,268,185],{"class":184},[178,270,271],{"class":184}," class",[178,273,274],{"class":191}," RealDatabase",[178,276,277],{"class":184}," implements",[178,279,192],{"class":191},[178,281,196],{"class":195},[178,283,284,287,290,292,295],{"class":180,"line":199},[178,285,286],{"class":184},"    public",[178,288,289],{"class":184}," void",[178,291,206],{"class":205},[178,293,294],{"class":195},"()",[178,296,196],{"class":195},[178,298,299,302,304,308,310,313,315,319],{"class":180,"line":212},[178,300,301],{"class":248},"        System",[178,303,127],{"class":195},[178,305,307],{"class":306},"s4Awn","out",[178,309,127],{"class":195},[178,311,312],{"class":205},"println",[178,314,242],{"class":195},[178,316,318],{"class":317},"sUOzB","\"Connecting to real database...\"",[178,320,252],{"class":195},[178,322,323],{"class":180,"line":219},[178,324,325],{"class":195},"    }\n",[178,327,328],{"class":180,"line":229},[178,329,216],{"emptyLinePlaceholder":215},[178,331,332,334,336,338,340],{"class":180,"line":234},[178,333,286],{"class":184},[178,335,289],{"class":184},[178,337,224],{"class":205},[178,339,294],{"class":195},[178,341,196],{"class":195},[178,343,344,346,348,350,352,354,356,359],{"class":180,"line":255},[178,345,301],{"class":248},[178,347,127],{"class":195},[178,349,307],{"class":306},[178,351,127],{"class":195},[178,353,312],{"class":205},[178,355,242],{"class":195},[178,357,358],{"class":317},"\"Disconnecting from real database...\"",[178,360,252],{"class":195},[178,362,364],{"class":180,"line":363},8,[178,365,325],{"class":195},[178,367,369],{"class":180,"line":368},9,[178,370,216],{"emptyLinePlaceholder":215},[178,372,374,376,378,380,382,384,386,389],{"class":180,"line":373},10,[178,375,286],{"class":184},[178,377,289],{"class":184},[178,379,239],{"class":205},[178,381,242],{"class":195},[178,383,245],{"class":184},[178,385,249],{"class":248},[178,387,388],{"class":195},")",[178,390,196],{"class":195},[178,392,394,396,398,400,402,404,406,409,412,415,418,421],{"class":180,"line":393},11,[178,395,301],{"class":248},[178,397,127],{"class":195},[178,399,307],{"class":306},[178,401,127],{"class":195},[178,403,312],{"class":205},[178,405,242],{"class":195},[178,407,408],{"class":317},"\"Executing query: \"",[178,410,411],{"class":195}," +",[178,413,414],{"class":248}," query ",[178,416,417],{"class":195},"+",[178,419,420],{"class":317}," \" on real database\"",[178,422,252],{"class":195},[178,424,426],{"class":180,"line":425},12,[178,427,325],{"class":195},[178,429,431],{"class":180,"line":430},13,[178,432,258],{"class":195},[168,434,437],{"className":170,"code":435,"filename":436,"language":173,"meta":174,"style":174},"public class DatabaseProxy implements Database {\n    private RealDatabase realDatabase;\n    private boolean connected;\n\n    public void connect() {\n        if (!connected) {\n            realDatabase = new RealDatabase();\n            realDatabase.connect();\n            connected = true;\n        }\n    }\n\n    public void disconnect() {\n        if (connected) {\n            realDatabase.disconnect();\n            connected = false;\n        }\n    }\n\n    public void executeQuery(String query) {\n        if (connected) {\n            realDatabase.executeQuery(query);\n        } else {\n            System.out.println(\"Not connected to the real database\");\n        }\n    }\n}\n","DatabaseProxy.java",[101,438,439,454,467,479,483,495,510,525,536,549,554,558,562,574,588,599,611,616,621,626,645,658,674,685,705,710,715],{"__ignoreMap":174},[178,440,441,443,445,448,450,452],{"class":180,"line":181},[178,442,185],{"class":184},[178,444,271],{"class":184},[178,446,447],{"class":191}," DatabaseProxy",[178,449,277],{"class":184},[178,451,192],{"class":191},[178,453,196],{"class":195},[178,455,456,459,461,464],{"class":180,"line":199},[178,457,458],{"class":184},"    private",[178,460,274],{"class":184},[178,462,463],{"class":248}," realDatabase",[178,465,466],{"class":195},";\n",[178,468,469,471,474,477],{"class":180,"line":212},[178,470,458],{"class":184},[178,472,473],{"class":184}," boolean",[178,475,476],{"class":248}," connected",[178,478,466],{"class":195},[178,480,481],{"class":180,"line":219},[178,482,216],{"emptyLinePlaceholder":215},[178,484,485,487,489,491,493],{"class":180,"line":229},[178,486,286],{"class":184},[178,488,289],{"class":184},[178,490,206],{"class":205},[178,492,294],{"class":195},[178,494,196],{"class":195},[178,496,497,500,503,506,508],{"class":180,"line":234},[178,498,499],{"class":184},"        if",[178,501,502],{"class":195}," (!",[178,504,505],{"class":248},"connected",[178,507,388],{"class":195},[178,509,196],{"class":195},[178,511,512,515,518,521,523],{"class":180,"line":255},[178,513,514],{"class":248},"            realDatabase ",[178,516,517],{"class":195},"=",[178,519,520],{"class":184}," new",[178,522,274],{"class":205},[178,524,209],{"class":195},[178,526,527,530,532,534],{"class":180,"line":363},[178,528,529],{"class":248},"            realDatabase",[178,531,127],{"class":195},[178,533,118],{"class":205},[178,535,209],{"class":195},[178,537,538,541,543,547],{"class":180,"line":368},[178,539,540],{"class":248},"            connected ",[178,542,517],{"class":195},[178,544,546],{"class":545},"sheII"," true",[178,548,466],{"class":195},[178,550,551],{"class":180,"line":373},[178,552,553],{"class":195},"        }\n",[178,555,556],{"class":180,"line":393},[178,557,325],{"class":195},[178,559,560],{"class":180,"line":425},[178,561,216],{"emptyLinePlaceholder":215},[178,563,564,566,568,570,572],{"class":180,"line":430},[178,565,286],{"class":184},[178,567,289],{"class":184},[178,569,224],{"class":205},[178,571,294],{"class":195},[178,573,196],{"class":195},[178,575,577,579,582,584,586],{"class":180,"line":576},14,[178,578,499],{"class":184},[178,580,581],{"class":195}," (",[178,583,505],{"class":248},[178,585,388],{"class":195},[178,587,196],{"class":195},[178,589,591,593,595,597],{"class":180,"line":590},15,[178,592,529],{"class":248},[178,594,127],{"class":195},[178,596,122],{"class":205},[178,598,209],{"class":195},[178,600,602,604,606,609],{"class":180,"line":601},16,[178,603,540],{"class":248},[178,605,517],{"class":195},[178,607,608],{"class":545}," false",[178,610,466],{"class":195},[178,612,614],{"class":180,"line":613},17,[178,615,553],{"class":195},[178,617,619],{"class":180,"line":618},18,[178,620,325],{"class":195},[178,622,624],{"class":180,"line":623},19,[178,625,216],{"emptyLinePlaceholder":215},[178,627,629,631,633,635,637,639,641,643],{"class":180,"line":628},20,[178,630,286],{"class":184},[178,632,289],{"class":184},[178,634,239],{"class":205},[178,636,242],{"class":195},[178,638,245],{"class":184},[178,640,249],{"class":248},[178,642,388],{"class":195},[178,644,196],{"class":195},[178,646,648,650,652,654,656],{"class":180,"line":647},21,[178,649,499],{"class":184},[178,651,581],{"class":195},[178,653,505],{"class":248},[178,655,388],{"class":195},[178,657,196],{"class":195},[178,659,661,663,665,667,669,672],{"class":180,"line":660},22,[178,662,529],{"class":248},[178,664,127],{"class":195},[178,666,126],{"class":205},[178,668,242],{"class":195},[178,670,671],{"class":248},"query",[178,673,252],{"class":195},[178,675,677,680,683],{"class":180,"line":676},23,[178,678,679],{"class":195},"        }",[178,681,682],{"class":184}," else",[178,684,196],{"class":195},[178,686,687,690,692,694,696,698,700,703],{"class":180,"line":5},[178,688,689],{"class":248},"            System",[178,691,127],{"class":195},[178,693,307],{"class":306},[178,695,127],{"class":195},[178,697,312],{"class":205},[178,699,242],{"class":195},[178,701,702],{"class":317},"\"Not connected to the real database\"",[178,704,252],{"class":195},[178,706,708],{"class":180,"line":707},25,[178,709,553],{"class":195},[178,711,713],{"class":180,"line":712},26,[178,714,325],{"class":195},[178,716,718],{"class":180,"line":717},27,[178,719,258],{"class":195},[168,721,724],{"className":170,"code":722,"filename":723,"language":173,"meta":174,"style":174},"public class Demo {\n    public static void main(String[] args) {\n        Database proxy = new DatabaseProxy();\n        \n        proxy.connect();\n        proxy.executeQuery(\"SELECT * FROM users\");\n        proxy.disconnect();\n    }\n}\n","Demo.java",[101,725,726,737,763,779,784,795,810,820,824],{"__ignoreMap":174},[178,727,728,730,732,735],{"class":180,"line":181},[178,729,185],{"class":184},[178,731,271],{"class":184},[178,733,734],{"class":191}," Demo",[178,736,196],{"class":195},[178,738,739,741,744,746,749,751,753,756,759,761],{"class":180,"line":199},[178,740,286],{"class":184},[178,742,743],{"class":184}," static",[178,745,289],{"class":184},[178,747,748],{"class":205}," main",[178,750,242],{"class":195},[178,752,245],{"class":184},[178,754,755],{"class":195},"[]",[178,757,758],{"class":248}," args",[178,760,388],{"class":195},[178,762,196],{"class":195},[178,764,765,768,771,773,775,777],{"class":180,"line":212},[178,766,767],{"class":184},"        Database",[178,769,770],{"class":248}," proxy ",[178,772,517],{"class":195},[178,774,520],{"class":184},[178,776,447],{"class":205},[178,778,209],{"class":195},[178,780,781],{"class":180,"line":219},[178,782,783],{"class":248},"        \n",[178,785,786,789,791,793],{"class":180,"line":229},[178,787,788],{"class":248},"        proxy",[178,790,127],{"class":195},[178,792,118],{"class":205},[178,794,209],{"class":195},[178,796,797,799,801,803,805,808],{"class":180,"line":234},[178,798,788],{"class":248},[178,800,127],{"class":195},[178,802,126],{"class":205},[178,804,242],{"class":195},[178,806,807],{"class":317},"\"SELECT * FROM users\"",[178,809,252],{"class":195},[178,811,812,814,816,818],{"class":180,"line":255},[178,813,788],{"class":248},[178,815,127],{"class":195},[178,817,122],{"class":205},[178,819,209],{"class":195},[178,821,822],{"class":180,"line":363},[178,823,325],{"class":195},[178,825,826],{"class":180,"line":368},[178,827,258],{"class":195},[32,829,830,831,833],{},"Running ",[101,832,156],{}," prints:",[168,835,840],{"className":836,"code":838,"language":839,"meta":174},[837],"language-text","Connecting to real database...\nExecuting query: SELECT * FROM users on real database\nDisconnecting from real database...\n","text",[101,841,838],{"__ignoreMap":174},[843,844,845],"style",{},"html pre.shiki code .sVsk0, html code.shiki .sVsk0{--shiki-default:#9D9FFE;--shiki-light:#6762D3}html pre.shiki code .sNwy7, html code.shiki .sNwy7{--shiki-default:#D4D7FE;--shiki-light:#3F3B87}html pre.shiki code .sVG6I, html code.shiki .sVG6I{--shiki-default:#85858F;--shiki-light:#71717A}html pre.shiki code .sVz7n, html code.shiki .sVz7n{--shiki-default:#EDEDEF;--shiki-light:#0B0B0C}html pre.shiki code .sWFPS, html code.shiki .sWFPS{--shiki-default:#C4C4CC;--shiki-light:#3F3F46}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .s4Awn, html code.shiki .s4Awn{--shiki-default:#C5DDFE;--shiki-light:#534DAF}html pre.shiki code .sUOzB, html code.shiki .sUOzB{--shiki-default:#9EC7FE;--shiki-light:#2873D1}html pre.shiki code .sheII, html code.shiki .sheII{--shiki-default:#70ADFF;--shiki-light:#195CAE}",{"title":174,"searchDepth":199,"depth":199,"links":847},[848,849,850,854,855],{"id":29,"depth":199,"text":30},{"id":43,"depth":199,"text":44},{"id":63,"depth":199,"text":64,"children":851},[852,853],{"id":68,"depth":212,"text":69},{"id":83,"depth":212,"text":84},{"id":95,"depth":199,"text":96},{"id":165,"depth":199,"text":166},"The Proxy pattern puts a stand-in in front of a real object to control access to it: create it only when needed, check calls, or reach it over a network. Explained with a worked Java example of a database.","A database that connects only when asked","md","Structural","lucide:shield-check",{},"\u002Flearn\u002Fdesign-patterns\u002Fproxy","---\ntitle: Proxy\ngroup: Structural\nicon: lucide:shield-check\nsummary: 'A stand-in with the same interface as the real object, which controls when and how the real one is used.'\ndescription: 'The Proxy pattern puts a stand-in in front of a real object to control access to it: create it only when needed, check calls, or reach it over a network. Explained with a worked Java example of a database.'\nexample: 'A database that connects only when asked'\norder: 7\nsource: https:\u002F\u002Fgithub.com\u002FHaythamasalama\u002FdesignPattern\u002Ftree\u002Fmaster\u002Fsrc\u002FStructural\u002FProxy\n---\n\n## The idea\n\nSometimes you want to control access to an object without changing it or its callers. The object may be expensive to create, it may live on another machine, or only some callers may be allowed to use it.\n\nA proxy is a stand-in with the same interface as the real object. Callers use the proxy as if it were the real thing. The proxy holds a reference to the real object and decides when to create it, whether to let a call through, and what to do before or after passing it on.\n\nThe Gang of Four name a few kinds. A virtual proxy creates the real object only when it is first needed. A protection proxy checks whether a call is allowed. A remote proxy stands in for an object that lives somewhere else, such as on a server.\n\n## When to use it\n\n- The real object is expensive to create, and you want to wait until it is used.\n- You want to check permissions or state before a call reaches the real object.\n- The real object lives on another machine, and callers shouldn't have to deal with the network.\n- You want to add logging, caching or call counting without touching the real class.\n\n## Pros and cons\n\n### Pros\n\n- It controls access to an object without the object or its callers changing.\n- It can stand in for a remote object, so callers treat it as a local one.\n- It can create the real object late, or not at all if it is never used.\n\n### Cons\n\n- It adds a layer between the caller and the real object, which can slow responses down.\n- It adds a class, and the proxy must follow every change to the interface.\n\n## The example\n\nThe example wraps a database. The proxy creates the real database only when `connect()` is called, and refuses queries while it is not connected.\n\n- **`Database`**: the subject interface shared by the proxy and the real object: `connect`, `disconnect` and `executeQuery`.\n- **`RealDatabase`**: the real subject, which does the actual work.\n- **`DatabaseProxy`**: the proxy. It creates a `RealDatabase` in `connect()`, not before, and keeps track of whether it is connected. It passes queries through only while connected, and prints a message otherwise.\n- **`Demo`**: the client. It holds the proxy as a `Database` and never sees `RealDatabase`.\n\n## The code\n\n```java [Database.java]\npublic interface Database {\n    void connect();\n\n    void disconnect();\n\n    void executeQuery(String query);\n}\n```\n\n```java [RealDatabase.java]\npublic class RealDatabase implements Database {\n    public void connect() {\n        System.out.println(\"Connecting to real database...\");\n    }\n\n    public void disconnect() {\n        System.out.println(\"Disconnecting from real database...\");\n    }\n\n    public void executeQuery(String query) {\n        System.out.println(\"Executing query: \" + query + \" on real database\");\n    }\n}\n```\n\n```java [DatabaseProxy.java]\npublic class DatabaseProxy implements Database {\n    private RealDatabase realDatabase;\n    private boolean connected;\n\n    public void connect() {\n        if (!connected) {\n            realDatabase = new RealDatabase();\n            realDatabase.connect();\n            connected = true;\n        }\n    }\n\n    public void disconnect() {\n        if (connected) {\n            realDatabase.disconnect();\n            connected = false;\n        }\n    }\n\n    public void executeQuery(String query) {\n        if (connected) {\n            realDatabase.executeQuery(query);\n        } else {\n            System.out.println(\"Not connected to the real database\");\n        }\n    }\n}\n```\n\n```java [Demo.java]\npublic class Demo {\n    public static void main(String[] args) {\n        Database proxy = new DatabaseProxy();\n        \n        proxy.connect();\n        proxy.executeQuery(\"SELECT * FROM users\");\n        proxy.disconnect();\n    }\n}\n```\n\nRunning `Demo` prints:\n\n```text\nConnecting to real database...\nExecuting query: SELECT * FROM users on real database\nDisconnecting from real database...\n```\n",{"title":22,"description":856},{"loc":862},"https:\u002F\u002Fgithub.com\u002FHaythamasalama\u002FdesignPattern\u002Ftree\u002Fmaster\u002Fsrc\u002FStructural\u002FProxy","learn\u002Fdesign-patterns\u002Fproxy","A stand-in with the same interface as the real object, which controls when and how the real one is used.","JFL9Fpr-Yh_ySTmfR81u_BvDSeDyp_GUdFawy0YtyOk",[871,876,881,886,891,896,901],{"path":872,"title":873,"icon":874,"summary":875,"order":181},"\u002Flearn\u002Fdesign-patterns\u002Fadapter","Adapter","lucide:plug","A thin wrapper that lets a class work with code that expects a different interface.",{"path":877,"title":878,"icon":879,"summary":880,"order":199},"\u002Flearn\u002Fdesign-patterns\u002Fbridge","Bridge","lucide:bridge","Split a class into two parts that can change on their own: what it does, and how it gets done.",{"path":882,"title":883,"icon":884,"summary":885,"order":212},"\u002Flearn\u002Fdesign-patterns\u002Fcomposite","Composite","lucide:network","Treat a single object and a group of objects the same way, by building them into a tree.",{"path":887,"title":888,"icon":889,"summary":890,"order":219},"\u002Flearn\u002Fdesign-patterns\u002Fdecorator","Decorator","lucide:gift","Wrap an object in another object that adds behaviour, without changing the original class.",{"path":892,"title":893,"icon":894,"summary":895,"order":229},"\u002Flearn\u002Fdesign-patterns\u002Ffacade","Facade","lucide:door-open","One simple class in front of a complex system, so callers talk to it instead of to every part.",{"path":897,"title":898,"icon":899,"summary":900,"order":234},"\u002Flearn\u002Fdesign-patterns\u002Fflyweight","Flyweight","lucide:feather","Share the common part of many similar objects, so large numbers of them cost little memory.",{"path":862,"title":22,"icon":860,"summary":868,"order":255},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":903},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 14c.2-1 .7-1.7 1.5-2.5c1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5c.7.7 1.3 1.5 1.5 2.5m0 4h6m-5 4h4\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":905},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3zM7 16.5l-4.74-2.85M7 16.5l5-3m-5 3v5.17m5-8.17V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5zm5 3l-5-3m5 3l4.74-2.85M17 16.5v5.17\"\u002F>\u003Cpath d=\"M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3l5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0zM12 8L7.26 5.15M12 8l4.74-2.85M12 13.5V8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":907},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 22v-5m3-9V2m2 6a1 1 0 0 1 1 1v4a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1zM9 8V2\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":909},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 9.728V16m4-6.272V16m4 4V4m4 7l-4-4A7.5 7.5 0 0 1 6 7l-4 4m20 5H2m4 4V4\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":911},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"6\" height=\"6\" x=\"16\" y=\"16\" rx=\"1\"\u002F>\u003Crect width=\"6\" height=\"6\" x=\"2\" y=\"16\" rx=\"1\"\u002F>\u003Crect width=\"6\" height=\"6\" x=\"9\" y=\"2\" rx=\"1\"\u002F>\u003Cpath d=\"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3m-7-4V8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":913},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12 7v14m8-10v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8m3.5-4a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5a1 1 0 0 1 0 5\"\u002F>\u003Crect width=\"18\" height=\"4\" x=\"3\" y=\"7\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":915},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 21H2m8-18H7a2 2 0 0 0-2 2v16m9-9h.01\"\u002F>\u003Cpath d=\"M19 21V5a2 2 0 0 0-1.675-1.974l-6.163-1.013A1 1 0 0 0 10 3v18a1 1 0 0 0 1.124.992zm3 0h-3\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":917},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.086 18.412A2 2 0 0 1 12.67 19H5v-7.672a2 2 0 0 1 .586-1.414L11.75 3.75a6 6 0 1 1 8.49 8.49zM16 8L2 22m15.488-7H9\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":919},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\"\u002F>\u003Cpath d=\"m9 12l2 2l4-4\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":921},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fg>",1793131416691]