[{"data":1,"prerenderedAt":1049},["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\u002Fcomposite":20,"pattern-group:\u002Flearn\u002Fdesign-patterns\u002Fcomposite":997,"i-lucide:lightbulb":1029,"i-lucide:boxes":1031,"i-lucide:plug":1033,"i-lucide:bridge":1035,"i-lucide:network":1037,"i-lucide:gift":1039,"i-lucide:door-open":1041,"i-lucide:feather":1043,"i-lucide:shield-check":1045,"i-lucide:copy":1047},{"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":983,"example":984,"extension":985,"group":986,"icon":987,"meta":988,"navigation":287,"order":238,"path":989,"rawbody":990,"seo":991,"sitemap":992,"source":993,"stem":994,"summary":995,"__hash__":996},"patterns\u002Flearn\u002Fdesign-patterns\u002Fcomposite.md","Composite",{"type":24,"value":25,"toc":973},"minimark",[26,31,35,38,41,45,61,65,70,86,90,110,114,117,186,189,193,242,389,721,955,961,969],[27,28,30],"h2",{"id":29},"the-idea","The idea",[32,33,34],"p",{},"Many things are trees. A folder holds files and other folders. A menu holds items and sub-menus. An order holds products and boxes of products. Code that works with these often has to ask, at every step, \"is this a single item or a group?\"",[32,36,37],{},"The Composite pattern removes that question. Single items, the leaves, and groups, the composites, share one interface. A composite keeps a list of children of that interface type and passes each call down to them. So the client calls one method on the root, and the whole tree responds.",[32,39,40],{},"The Gang of Four call this a part-whole hierarchy: a whole is made of parts, and a part can itself be a whole.",[27,42,44],{"id":43},"when-to-use-it","When to use it",[46,47,48,52,55,58],"ul",{},[49,50,51],"li",{},"Your data forms a tree, such as folders, menus, organisation charts or screen layouts.",[49,53,54],{},"You want client code to treat single objects and groups in the same way.",[49,56,57],{},"An operation on a group should apply to everything inside it, such as working out a folder's size or drawing a group of shapes.",[49,59,60],{},"You want to add new kinds of items without changing the code that walks the tree.",[27,62,64],{"id":63},"pros-and-cons","Pros and cons",[66,67,69],"h3",{"id":68},"pros","Pros",[46,71,72,75,83],{},[49,73,74],{},"It represents part-whole hierarchies directly.",[49,76,77,78,82],{},"Clients treat single objects and groups the same way, so they need fewer ",[79,80,81],"code",{},"if"," checks.",[49,84,85],{},"Adding a new kind of leaf or composite needs no change to existing code.",[66,87,89],{"id":88},"cons","Cons",[46,91,92,95],{},[49,93,94],{},"The shared interface can become too general. It is hard to stop a composite from accepting children it shouldn't.",[49,96,97,98,101,102,105,106,109],{},"You must choose where ",[79,99,100],{},"add"," and ",[79,103,104],{},"remove"," live. Here they are only on ",[79,107,108],{},"Directory",", which is safer, but clients must know when they hold a directory.",[27,111,113],{"id":112},"the-example","The example",[32,115,116],{},"The example is a small file system. Directories hold files and other directories, and showing the name of a directory shows everything inside it.",[46,118,119,132,143,164],{},[49,120,121,127,128,131],{},[122,123,124],"strong",{},[79,125,126],{},"FileSystemComponent",": the component interface shared by files and directories, with ",[79,129,130],{},"showName()",".",[49,133,134,139,140,142],{},[122,135,136],{},[79,137,138],{},"File",": the leaf. It has no children, and ",[79,141,130],{}," prints its own name.",[49,144,145,149,150,152,153,101,155,157,158,160,161,163],{},[122,146,147],{},[79,148,108],{},": the composite. It keeps a list of ",[79,151,126],{}," children, with ",[79,154,100],{},[79,156,104],{},". Its ",[79,159,130],{}," prints its own name, then calls ",[79,162,130],{}," on each child.",[49,165,166,171,172,175,176,179,180,182,183,131],{},[122,167,168],{},[79,169,170],{},"Demo",": builds ",[79,173,174],{},"root\u002Fhome\u002Fuser"," with two files in ",[79,177,178],{},"user",", then calls ",[79,181,130],{}," once, on ",[79,184,185],{},"root",[32,187,188],{},"That one call prints every name in the tree, each directory before its contents.",[27,190,192],{"id":191},"the-code","The code",[194,195,201],"pre",{"className":196,"code":197,"filename":198,"language":199,"meta":200,"style":200},"language-java shiki shiki-themes haytham-dark haytham-light","public interface FileSystemComponent {\n    void showName();\n}\n","FileSystemComponent.java","java","",[79,202,203,223,236],{"__ignoreMap":200},[204,205,208,212,215,219],"span",{"class":206,"line":207},"line",1,[204,209,211],{"class":210},"sVsk0","public",[204,213,214],{"class":210}," interface",[204,216,218],{"class":217},"sNwy7"," FileSystemComponent",[204,220,222],{"class":221},"sVG6I"," {\n",[204,224,226,229,233],{"class":206,"line":225},2,[204,227,228],{"class":210},"    void",[204,230,232],{"class":231},"sVz7n"," showName",[204,234,235],{"class":221},"();\n",[204,237,239],{"class":206,"line":238},3,[204,240,241],{"class":221},"}\n",[194,243,246],{"className":196,"code":244,"filename":245,"language":199,"meta":200,"style":200},"public class File implements FileSystemComponent {\n    private final String name;\n\n    public File(String name) {\n        this.name = name;\n    }\n\n    public void showName() {\n        System.out.println(name);\n    }\n}\n","File.java",[79,247,248,265,283,289,310,330,336,341,356,379,384],{"__ignoreMap":200},[204,249,250,252,255,258,261,263],{"class":206,"line":207},[204,251,211],{"class":210},[204,253,254],{"class":210}," class",[204,256,257],{"class":217}," File",[204,259,260],{"class":210}," implements",[204,262,218],{"class":217},[204,264,222],{"class":221},[204,266,267,270,273,276,280],{"class":206,"line":225},[204,268,269],{"class":210},"    private",[204,271,272],{"class":210}," final",[204,274,275],{"class":210}," String",[204,277,279],{"class":278},"sWFPS"," name",[204,281,282],{"class":221},";\n",[204,284,285],{"class":206,"line":238},[204,286,288],{"emptyLinePlaceholder":287},true,"\n",[204,290,292,295,297,300,303,305,308],{"class":206,"line":291},4,[204,293,294],{"class":210},"    public",[204,296,257],{"class":231},[204,298,299],{"class":221},"(",[204,301,302],{"class":210},"String",[204,304,279],{"class":278},[204,306,307],{"class":221},")",[204,309,222],{"class":221},[204,311,313,317,319,323,326,328],{"class":206,"line":312},5,[204,314,316],{"class":315},"sheII","        this",[204,318,131],{"class":221},[204,320,322],{"class":321},"s4Awn","name",[204,324,325],{"class":221}," =",[204,327,279],{"class":278},[204,329,282],{"class":221},[204,331,333],{"class":206,"line":332},6,[204,334,335],{"class":221},"    }\n",[204,337,339],{"class":206,"line":338},7,[204,340,288],{"emptyLinePlaceholder":287},[204,342,344,346,349,351,354],{"class":206,"line":343},8,[204,345,294],{"class":210},[204,347,348],{"class":210}," void",[204,350,232],{"class":231},[204,352,353],{"class":221},"()",[204,355,222],{"class":221},[204,357,359,362,364,367,369,372,374,376],{"class":206,"line":358},9,[204,360,361],{"class":278},"        System",[204,363,131],{"class":221},[204,365,366],{"class":321},"out",[204,368,131],{"class":221},[204,370,371],{"class":231},"println",[204,373,299],{"class":221},[204,375,322],{"class":278},[204,377,378],{"class":221},");\n",[204,380,382],{"class":206,"line":381},10,[204,383,335],{"class":221},[204,385,387],{"class":206,"line":386},11,[204,388,241],{"class":221},[194,390,393],{"className":196,"code":391,"filename":392,"language":199,"meta":200,"style":200},"import java.util.ArrayList;\nimport java.util.List;\n\npublic class Directory implements FileSystemComponent {\n    private final String name;\n    private final List\u003CFileSystemComponent> children;\n\n    public Directory(String name) {\n        this.name = name;\n        children = new ArrayList\u003C>();\n    }\n\n    public void add(FileSystemComponent component) {\n        children.add(component);\n    }\n\n    public void remove(FileSystemComponent component) {\n        children.remove(component);\n    }\n\n    public void showName() {\n        System.out.println(name);\n        for (FileSystemComponent child : children) {\n            child.showName();\n        }\n    }\n}\n","Directory.java",[79,394,395,415,432,436,451,463,485,489,505,519,536,540,545,566,583,588,593,613,628,633,638,651,670,693,705,711,716],{"__ignoreMap":200},[204,396,397,400,403,405,408,410,413],{"class":206,"line":207},[204,398,399],{"class":210},"import",[204,401,402],{"class":210}," java",[204,404,131],{"class":221},[204,406,407],{"class":210},"util",[204,409,131],{"class":221},[204,411,412],{"class":210},"ArrayList",[204,414,282],{"class":221},[204,416,417,419,421,423,425,427,430],{"class":206,"line":225},[204,418,399],{"class":210},[204,420,402],{"class":210},[204,422,131],{"class":221},[204,424,407],{"class":210},[204,426,131],{"class":221},[204,428,429],{"class":210},"List",[204,431,282],{"class":221},[204,433,434],{"class":206,"line":238},[204,435,288],{"emptyLinePlaceholder":287},[204,437,438,440,442,445,447,449],{"class":206,"line":291},[204,439,211],{"class":210},[204,441,254],{"class":210},[204,443,444],{"class":217}," Directory",[204,446,260],{"class":210},[204,448,218],{"class":217},[204,450,222],{"class":221},[204,452,453,455,457,459,461],{"class":206,"line":312},[204,454,269],{"class":210},[204,456,272],{"class":210},[204,458,275],{"class":210},[204,460,279],{"class":278},[204,462,282],{"class":221},[204,464,465,467,469,472,475,477,480,483],{"class":206,"line":332},[204,466,269],{"class":210},[204,468,272],{"class":210},[204,470,471],{"class":210}," List",[204,473,474],{"class":221},"\u003C",[204,476,126],{"class":210},[204,478,479],{"class":221},">",[204,481,482],{"class":278}," children",[204,484,282],{"class":221},[204,486,487],{"class":206,"line":338},[204,488,288],{"emptyLinePlaceholder":287},[204,490,491,493,495,497,499,501,503],{"class":206,"line":343},[204,492,294],{"class":210},[204,494,444],{"class":231},[204,496,299],{"class":221},[204,498,302],{"class":210},[204,500,279],{"class":278},[204,502,307],{"class":221},[204,504,222],{"class":221},[204,506,507,509,511,513,515,517],{"class":206,"line":358},[204,508,316],{"class":315},[204,510,131],{"class":221},[204,512,322],{"class":321},[204,514,325],{"class":221},[204,516,279],{"class":278},[204,518,282],{"class":221},[204,520,521,524,527,530,533],{"class":206,"line":381},[204,522,523],{"class":278},"        children ",[204,525,526],{"class":221},"=",[204,528,529],{"class":210}," new",[204,531,532],{"class":210}," ArrayList",[204,534,535],{"class":221},"\u003C>();\n",[204,537,538],{"class":206,"line":386},[204,539,335],{"class":221},[204,541,543],{"class":206,"line":542},12,[204,544,288],{"emptyLinePlaceholder":287},[204,546,548,550,552,555,557,559,562,564],{"class":206,"line":547},13,[204,549,294],{"class":210},[204,551,348],{"class":210},[204,553,554],{"class":231}," add",[204,556,299],{"class":221},[204,558,126],{"class":210},[204,560,561],{"class":278}," component",[204,563,307],{"class":221},[204,565,222],{"class":221},[204,567,569,572,574,576,578,581],{"class":206,"line":568},14,[204,570,571],{"class":278},"        children",[204,573,131],{"class":221},[204,575,100],{"class":231},[204,577,299],{"class":221},[204,579,580],{"class":278},"component",[204,582,378],{"class":221},[204,584,586],{"class":206,"line":585},15,[204,587,335],{"class":221},[204,589,591],{"class":206,"line":590},16,[204,592,288],{"emptyLinePlaceholder":287},[204,594,596,598,600,603,605,607,609,611],{"class":206,"line":595},17,[204,597,294],{"class":210},[204,599,348],{"class":210},[204,601,602],{"class":231}," remove",[204,604,299],{"class":221},[204,606,126],{"class":210},[204,608,561],{"class":278},[204,610,307],{"class":221},[204,612,222],{"class":221},[204,614,616,618,620,622,624,626],{"class":206,"line":615},18,[204,617,571],{"class":278},[204,619,131],{"class":221},[204,621,104],{"class":231},[204,623,299],{"class":221},[204,625,580],{"class":278},[204,627,378],{"class":221},[204,629,631],{"class":206,"line":630},19,[204,632,335],{"class":221},[204,634,636],{"class":206,"line":635},20,[204,637,288],{"emptyLinePlaceholder":287},[204,639,641,643,645,647,649],{"class":206,"line":640},21,[204,642,294],{"class":210},[204,644,348],{"class":210},[204,646,232],{"class":231},[204,648,353],{"class":221},[204,650,222],{"class":221},[204,652,654,656,658,660,662,664,666,668],{"class":206,"line":653},22,[204,655,361],{"class":278},[204,657,131],{"class":221},[204,659,366],{"class":321},[204,661,131],{"class":221},[204,663,371],{"class":231},[204,665,299],{"class":221},[204,667,322],{"class":278},[204,669,378],{"class":221},[204,671,673,676,679,681,684,687,689,691],{"class":206,"line":672},23,[204,674,675],{"class":210},"        for",[204,677,678],{"class":221}," (",[204,680,126],{"class":210},[204,682,683],{"class":278}," child ",[204,685,686],{"class":210},":",[204,688,482],{"class":278},[204,690,307],{"class":221},[204,692,222],{"class":221},[204,694,695,698,700,703],{"class":206,"line":5},[204,696,697],{"class":278},"            child",[204,699,131],{"class":221},[204,701,702],{"class":231},"showName",[204,704,235],{"class":221},[204,706,708],{"class":206,"line":707},25,[204,709,710],{"class":221},"        }\n",[204,712,714],{"class":206,"line":713},26,[204,715,335],{"class":221},[204,717,719],{"class":206,"line":718},27,[204,720,241],{"class":221},[194,722,725],{"className":196,"code":723,"filename":724,"language":199,"meta":200,"style":200},"public class Demo {\n    public static void main(String[] args) {\n        Directory root = new Directory(\"root\");\n        Directory home = new Directory(\"home\");\n        Directory user = new Directory(\"user\");\n        File file1 = new File(\"file1.txt\");\n        File file2 = new File(\"file2.txt\");\n\n        root.add(home);\n        home.add(user);\n        user.add(file1);\n        user.add(file2);\n\n        root.showName();\n    }\n}\n","Demo.java",[79,726,727,738,764,786,806,826,847,867,871,887,902,918,933,937,947,951],{"__ignoreMap":200},[204,728,729,731,733,736],{"class":206,"line":207},[204,730,211],{"class":210},[204,732,254],{"class":210},[204,734,735],{"class":217}," Demo",[204,737,222],{"class":221},[204,739,740,742,745,747,750,752,754,757,760,762],{"class":206,"line":225},[204,741,294],{"class":210},[204,743,744],{"class":210}," static",[204,746,348],{"class":210},[204,748,749],{"class":231}," main",[204,751,299],{"class":221},[204,753,302],{"class":210},[204,755,756],{"class":221},"[]",[204,758,759],{"class":278}," args",[204,761,307],{"class":221},[204,763,222],{"class":221},[204,765,766,769,772,774,776,778,780,784],{"class":206,"line":238},[204,767,768],{"class":210},"        Directory",[204,770,771],{"class":278}," root ",[204,773,526],{"class":221},[204,775,529],{"class":210},[204,777,444],{"class":231},[204,779,299],{"class":221},[204,781,783],{"class":782},"sUOzB","\"root\"",[204,785,378],{"class":221},[204,787,788,790,793,795,797,799,801,804],{"class":206,"line":291},[204,789,768],{"class":210},[204,791,792],{"class":278}," home ",[204,794,526],{"class":221},[204,796,529],{"class":210},[204,798,444],{"class":231},[204,800,299],{"class":221},[204,802,803],{"class":782},"\"home\"",[204,805,378],{"class":221},[204,807,808,810,813,815,817,819,821,824],{"class":206,"line":312},[204,809,768],{"class":210},[204,811,812],{"class":278}," user ",[204,814,526],{"class":221},[204,816,529],{"class":210},[204,818,444],{"class":231},[204,820,299],{"class":221},[204,822,823],{"class":782},"\"user\"",[204,825,378],{"class":221},[204,827,828,831,834,836,838,840,842,845],{"class":206,"line":332},[204,829,830],{"class":210},"        File",[204,832,833],{"class":278}," file1 ",[204,835,526],{"class":221},[204,837,529],{"class":210},[204,839,257],{"class":231},[204,841,299],{"class":221},[204,843,844],{"class":782},"\"file1.txt\"",[204,846,378],{"class":221},[204,848,849,851,854,856,858,860,862,865],{"class":206,"line":338},[204,850,830],{"class":210},[204,852,853],{"class":278}," file2 ",[204,855,526],{"class":221},[204,857,529],{"class":210},[204,859,257],{"class":231},[204,861,299],{"class":221},[204,863,864],{"class":782},"\"file2.txt\"",[204,866,378],{"class":221},[204,868,869],{"class":206,"line":343},[204,870,288],{"emptyLinePlaceholder":287},[204,872,873,876,878,880,882,885],{"class":206,"line":358},[204,874,875],{"class":278},"        root",[204,877,131],{"class":221},[204,879,100],{"class":231},[204,881,299],{"class":221},[204,883,884],{"class":278},"home",[204,886,378],{"class":221},[204,888,889,892,894,896,898,900],{"class":206,"line":381},[204,890,891],{"class":278},"        home",[204,893,131],{"class":221},[204,895,100],{"class":231},[204,897,299],{"class":221},[204,899,178],{"class":278},[204,901,378],{"class":221},[204,903,904,907,909,911,913,916],{"class":206,"line":386},[204,905,906],{"class":278},"        user",[204,908,131],{"class":221},[204,910,100],{"class":231},[204,912,299],{"class":221},[204,914,915],{"class":278},"file1",[204,917,378],{"class":221},[204,919,920,922,924,926,928,931],{"class":206,"line":542},[204,921,906],{"class":278},[204,923,131],{"class":221},[204,925,100],{"class":231},[204,927,299],{"class":221},[204,929,930],{"class":278},"file2",[204,932,378],{"class":221},[204,934,935],{"class":206,"line":547},[204,936,288],{"emptyLinePlaceholder":287},[204,938,939,941,943,945],{"class":206,"line":568},[204,940,875],{"class":278},[204,942,131],{"class":221},[204,944,702],{"class":231},[204,946,235],{"class":221},[204,948,949],{"class":206,"line":585},[204,950,335],{"class":221},[204,952,953],{"class":206,"line":590},[204,954,241],{"class":221},[32,956,957,958,960],{},"Running ",[79,959,170],{}," prints:",[194,962,967],{"className":963,"code":965,"language":966,"meta":200},[964],"language-text","root\nhome\nuser\nfile1.txt\nfile2.txt\n","text",[79,968,965],{"__ignoreMap":200},[970,971,972],"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 .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 .sWFPS, html code.shiki .sWFPS{--shiki-default:#C4C4CC;--shiki-light:#3F3F46}html pre.shiki code .sheII, html code.shiki .sheII{--shiki-default:#70ADFF;--shiki-light:#195CAE}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}",{"title":200,"searchDepth":225,"depth":225,"links":974},[975,976,977,981,982],{"id":29,"depth":225,"text":30},{"id":43,"depth":225,"text":44},{"id":63,"depth":225,"text":64,"children":978},[979,980],{"id":68,"depth":238,"text":69},{"id":88,"depth":238,"text":89},{"id":112,"depth":225,"text":113},{"id":191,"depth":225,"text":192},"The Composite pattern builds objects into a tree so that a single item and a whole group can be treated the same way. Explained with a worked Java example of files and directories in a file system.","Files and directories in a file system","md","Structural","lucide:network",{},"\u002Flearn\u002Fdesign-patterns\u002Fcomposite","---\ntitle: Composite\ngroup: Structural\nicon: lucide:network\nsummary: 'Treat a single object and a group of objects the same way, by building them into a tree.'\ndescription: 'The Composite pattern builds objects into a tree so that a single item and a whole group can be treated the same way. Explained with a worked Java example of files and directories in a file system.'\nexample: 'Files and directories in a file system'\norder: 3\nsource: https:\u002F\u002Fgithub.com\u002FHaythamasalama\u002FdesignPattern\u002Ftree\u002Fmaster\u002Fsrc\u002FStructural\u002FComposite\n---\n\n## The idea\n\nMany things are trees. A folder holds files and other folders. A menu holds items and sub-menus. An order holds products and boxes of products. Code that works with these often has to ask, at every step, \"is this a single item or a group?\"\n\nThe Composite pattern removes that question. Single items, the leaves, and groups, the composites, share one interface. A composite keeps a list of children of that interface type and passes each call down to them. So the client calls one method on the root, and the whole tree responds.\n\nThe Gang of Four call this a part-whole hierarchy: a whole is made of parts, and a part can itself be a whole.\n\n## When to use it\n\n- Your data forms a tree, such as folders, menus, organisation charts or screen layouts.\n- You want client code to treat single objects and groups in the same way.\n- An operation on a group should apply to everything inside it, such as working out a folder's size or drawing a group of shapes.\n- You want to add new kinds of items without changing the code that walks the tree.\n\n## Pros and cons\n\n### Pros\n\n- It represents part-whole hierarchies directly.\n- Clients treat single objects and groups the same way, so they need fewer `if` checks.\n- Adding a new kind of leaf or composite needs no change to existing code.\n\n### Cons\n\n- The shared interface can become too general. It is hard to stop a composite from accepting children it shouldn't.\n- You must choose where `add` and `remove` live. Here they are only on `Directory`, which is safer, but clients must know when they hold a directory.\n\n## The example\n\nThe example is a small file system. Directories hold files and other directories, and showing the name of a directory shows everything inside it.\n\n- **`FileSystemComponent`**: the component interface shared by files and directories, with `showName()`.\n- **`File`**: the leaf. It has no children, and `showName()` prints its own name.\n- **`Directory`**: the composite. It keeps a list of `FileSystemComponent` children, with `add` and `remove`. Its `showName()` prints its own name, then calls `showName()` on each child.\n- **`Demo`**: builds `root\u002Fhome\u002Fuser` with two files in `user`, then calls `showName()` once, on `root`.\n\nThat one call prints every name in the tree, each directory before its contents.\n\n## The code\n\n```java [FileSystemComponent.java]\npublic interface FileSystemComponent {\n    void showName();\n}\n```\n\n```java [File.java]\npublic class File implements FileSystemComponent {\n    private final String name;\n\n    public File(String name) {\n        this.name = name;\n    }\n\n    public void showName() {\n        System.out.println(name);\n    }\n}\n```\n\n```java [Directory.java]\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Directory implements FileSystemComponent {\n    private final String name;\n    private final List\u003CFileSystemComponent> children;\n\n    public Directory(String name) {\n        this.name = name;\n        children = new ArrayList\u003C>();\n    }\n\n    public void add(FileSystemComponent component) {\n        children.add(component);\n    }\n\n    public void remove(FileSystemComponent component) {\n        children.remove(component);\n    }\n\n    public void showName() {\n        System.out.println(name);\n        for (FileSystemComponent child : children) {\n            child.showName();\n        }\n    }\n}\n```\n\n```java [Demo.java]\npublic class Demo {\n    public static void main(String[] args) {\n        Directory root = new Directory(\"root\");\n        Directory home = new Directory(\"home\");\n        Directory user = new Directory(\"user\");\n        File file1 = new File(\"file1.txt\");\n        File file2 = new File(\"file2.txt\");\n\n        root.add(home);\n        home.add(user);\n        user.add(file1);\n        user.add(file2);\n\n        root.showName();\n    }\n}\n```\n\nRunning `Demo` prints:\n\n```text\nroot\nhome\nuser\nfile1.txt\nfile2.txt\n```\n",{"title":22,"description":983},{"loc":989},"https:\u002F\u002Fgithub.com\u002FHaythamasalama\u002FdesignPattern\u002Ftree\u002Fmaster\u002Fsrc\u002FStructural\u002FComposite","learn\u002Fdesign-patterns\u002Fcomposite","Treat a single object and a group of objects the same way, by building them into a tree.","w2tpo5v_ddA3bkI05e7QeiJF0axHtCWq9tsSmqc0umw",[998,1003,1008,1009,1014,1019,1024],{"path":999,"title":1000,"icon":1001,"summary":1002,"order":207},"\u002Flearn\u002Fdesign-patterns\u002Fadapter","Adapter","lucide:plug","A thin wrapper that lets a class work with code that expects a different interface.",{"path":1004,"title":1005,"icon":1006,"summary":1007,"order":225},"\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":989,"title":22,"icon":987,"summary":995,"order":238},{"path":1010,"title":1011,"icon":1012,"summary":1013,"order":291},"\u002Flearn\u002Fdesign-patterns\u002Fdecorator","Decorator","lucide:gift","Wrap an object in another object that adds behaviour, without changing the original class.",{"path":1015,"title":1016,"icon":1017,"summary":1018,"order":312},"\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":1020,"title":1021,"icon":1022,"summary":1023,"order":332},"\u002Flearn\u002Fdesign-patterns\u002Fflyweight","Flyweight","lucide:feather","Share the common part of many similar objects, so large numbers of them cost little memory.",{"path":1025,"title":1026,"icon":1027,"summary":1028,"order":338},"\u002Flearn\u002Fdesign-patterns\u002Fproxy","Proxy","lucide:shield-check","A stand-in with the same interface as the real object, which controls when and how the real one is used.",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1030},"\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":1032},"\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":1034},"\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":1036},"\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":1038},"\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":1040},"\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":1042},"\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":1044},"\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":1046},"\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":1048},"\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>",1793131416565]