[{"data":1,"prerenderedAt":809},["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\u002Ftemplate-method":20,"pattern-group:\u002Flearn\u002Fdesign-patterns\u002Ftemplate-method":750,"i-lucide:lightbulb":787,"i-lucide:workflow":789,"i-lucide:link":791,"i-lucide:square-terminal":793,"i-lucide:list-ordered":795,"i-lucide:bell":797,"i-lucide:toggle-left":799,"i-lucide:shuffle":801,"i-lucide:layout-template":803,"i-lucide:footprints":805,"i-lucide:copy":807},{"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":736,"example":737,"extension":738,"group":739,"icon":740,"meta":741,"navigation":261,"order":279,"path":742,"rawbody":743,"seo":744,"sitemap":745,"source":746,"stem":747,"summary":748,"__hash__":749},"patterns\u002Flearn\u002Fdesign-patterns\u002Ftemplate-method.md","Template Method",{"type":24,"value":25,"toc":726},"minimark",[26,31,35,38,41,45,61,65,70,81,85,96,100,103,167,171,393,462,528,594,708,714,722],[27,28,30],"h2",{"id":29},"the-idea","The idea",[32,33,34],"p",{},"Several classes often do the same task in the same order, with only one or two steps that differ. Importing a file always means opening it, reading it and closing it. Only the reading depends on the file type. If each importer writes all three steps, the shared steps are copied into every class.",[32,36,37],{},"The Template Method pattern puts the order of the steps in one method of a base class: the template method. Steps that are the same for everyone are written once, in the base class. Steps that differ are declared abstract, and each subclass fills them in.",[32,39,40],{},"The base class stays in control of the order. Subclasses can change a step, but not the sequence. This is sometimes called the Hollywood principle, \"don't call us, we'll call you\": the base class calls the subclass, not the other way round.",[27,42,44],{"id":43},"when-to-use-it","When to use it",[46,47,48,52,55,58],"ul",{},[49,50,51],"li",{},"Several classes run the same steps in the same order, and differ in only a few of them.",[49,53,54],{},"You want to stop subclasses from changing the order of a process, while letting them change its details.",[49,56,57],{},"You see the same code copied across sibling classes, with small changes.",[49,59,60],{},"You are writing a framework, and want its users to plug in their own code at fixed points.",[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 reuses code: shared steps are written once, in the base class.",[49,76,77],{},"Extending the algorithm is easy: a new variant is a subclass that fills in the missing steps.",[49,79,80],{},"The order of the steps is fixed in one place.",[66,82,84],{"id":83},"cons","Cons",[46,86,87,90,93],{},[49,88,89],{},"It adds classes to the system: one subclass for every variant.",[49,91,92],{},"It relies on inheritance, so each object's variant is fixed when it is created. Strategy uses composition, and can be swapped at runtime.",[49,94,95],{},"The more steps a template has, the harder it is to see which ones a subclass may change.",[27,97,99],{"id":98},"the-example","The example",[32,101,102],{},"The example imports files of different types. Every import opens the file, reads it and closes it, and only the reading depends on the type.",[46,104,105,138,159],{},[49,106,107,114,115,118,119,122,123,126,127,130,131,134,135,137],{},[108,109,110],"strong",{},[111,112,113],"code",{},"FileImporter",": the abstract class. ",[111,116,117],{},"importFile()"," is the template method. It is ",[111,120,121],{},"final",", so subclasses can't change the order, and it calls ",[111,124,125],{},"openFile()",", ",[111,128,129],{},"readFile()"," and ",[111,132,133],{},"closeFile()",". Opening and closing are written once here, and ",[111,136,129],{}," is abstract.",[49,139,140,126,145,130,150,155,156,158],{},[108,141,142],{},[111,143,144],{},"CsvFileImporter",[108,146,147],{},[111,148,149],{},"ExcelFileImporter",[108,151,152],{},[111,153,154],{},"WordFileImporter",": concrete classes. Each overrides only ",[111,157,129],{},".",[49,160,161,166],{},[108,162,163],{},[111,164,165],{},"Demo",": runs the Excel and Word importers. Both open and close the file in the same way, and differ only in the read step.",[27,168,170],{"id":169},"the-code","The code",[172,173,179],"pre",{"className":174,"code":175,"filename":176,"language":177,"meta":178,"style":178},"language-java shiki shiki-themes haytham-dark haytham-light","public abstract class FileImporter {\n    public void openFile() {\n        System.out.println(\"open file...\");\n    }\n\n    public void closeFile() {\n        System.out.println(\"close file...\");\n    }\n\n    abstract void readFile();\n\n    final public void importFile() {\n        this.openFile();\n        this.readFile();\n        this.closeFile();\n    }\n}\n","FileImporter.java","java","",[111,180,181,204,222,250,256,263,277,297,302,307,321,326,344,358,370,382,387],{"__ignoreMap":178},[182,183,186,190,193,196,200],"span",{"class":184,"line":185},"line",1,[182,187,189],{"class":188},"sVsk0","public",[182,191,192],{"class":188}," abstract",[182,194,195],{"class":188}," class",[182,197,199],{"class":198},"sNwy7"," FileImporter",[182,201,203],{"class":202},"sVG6I"," {\n",[182,205,207,210,213,217,220],{"class":184,"line":206},2,[182,208,209],{"class":188},"    public",[182,211,212],{"class":188}," void",[182,214,216],{"class":215},"sVz7n"," openFile",[182,218,219],{"class":202},"()",[182,221,203],{"class":202},[182,223,225,229,231,235,237,240,243,247],{"class":184,"line":224},3,[182,226,228],{"class":227},"sWFPS","        System",[182,230,158],{"class":202},[182,232,234],{"class":233},"s4Awn","out",[182,236,158],{"class":202},[182,238,239],{"class":215},"println",[182,241,242],{"class":202},"(",[182,244,246],{"class":245},"sUOzB","\"open file...\"",[182,248,249],{"class":202},");\n",[182,251,253],{"class":184,"line":252},4,[182,254,255],{"class":202},"    }\n",[182,257,259],{"class":184,"line":258},5,[182,260,262],{"emptyLinePlaceholder":261},true,"\n",[182,264,266,268,270,273,275],{"class":184,"line":265},6,[182,267,209],{"class":188},[182,269,212],{"class":188},[182,271,272],{"class":215}," closeFile",[182,274,219],{"class":202},[182,276,203],{"class":202},[182,278,280,282,284,286,288,290,292,295],{"class":184,"line":279},7,[182,281,228],{"class":227},[182,283,158],{"class":202},[182,285,234],{"class":233},[182,287,158],{"class":202},[182,289,239],{"class":215},[182,291,242],{"class":202},[182,293,294],{"class":245},"\"close file...\"",[182,296,249],{"class":202},[182,298,300],{"class":184,"line":299},8,[182,301,255],{"class":202},[182,303,305],{"class":184,"line":304},9,[182,306,262],{"emptyLinePlaceholder":261},[182,308,310,313,315,318],{"class":184,"line":309},10,[182,311,312],{"class":188},"    abstract",[182,314,212],{"class":188},[182,316,317],{"class":215}," readFile",[182,319,320],{"class":202},"();\n",[182,322,324],{"class":184,"line":323},11,[182,325,262],{"emptyLinePlaceholder":261},[182,327,329,332,335,337,340,342],{"class":184,"line":328},12,[182,330,331],{"class":188},"    final",[182,333,334],{"class":188}," public",[182,336,212],{"class":188},[182,338,339],{"class":215}," importFile",[182,341,219],{"class":202},[182,343,203],{"class":202},[182,345,347,351,353,356],{"class":184,"line":346},13,[182,348,350],{"class":349},"sheII","        this",[182,352,158],{"class":202},[182,354,355],{"class":215},"openFile",[182,357,320],{"class":202},[182,359,361,363,365,368],{"class":184,"line":360},14,[182,362,350],{"class":349},[182,364,158],{"class":202},[182,366,367],{"class":215},"readFile",[182,369,320],{"class":202},[182,371,373,375,377,380],{"class":184,"line":372},15,[182,374,350],{"class":349},[182,376,158],{"class":202},[182,378,379],{"class":215},"closeFile",[182,381,320],{"class":202},[182,383,385],{"class":184,"line":384},16,[182,386,255],{"class":202},[182,388,390],{"class":184,"line":389},17,[182,391,392],{"class":202},"}\n",[172,394,397],{"className":174,"code":395,"filename":396,"language":177,"meta":178,"style":178},"public class CsvFileImporter extends FileImporter {\n    @Override\n    public void readFile() {\n        System.out.println(\"read data from csv file...\");\n    }\n}\n","CsvFileImporter.java",[111,398,399,415,423,435,454,458],{"__ignoreMap":178},[182,400,401,403,405,408,411,413],{"class":184,"line":185},[182,402,189],{"class":188},[182,404,195],{"class":188},[182,406,407],{"class":198}," CsvFileImporter",[182,409,410],{"class":188}," extends",[182,412,199],{"class":198},[182,414,203],{"class":202},[182,416,417,420],{"class":184,"line":206},[182,418,419],{"class":202},"    @",[182,421,422],{"class":188},"Override\n",[182,424,425,427,429,431,433],{"class":184,"line":224},[182,426,209],{"class":188},[182,428,212],{"class":188},[182,430,317],{"class":215},[182,432,219],{"class":202},[182,434,203],{"class":202},[182,436,437,439,441,443,445,447,449,452],{"class":184,"line":252},[182,438,228],{"class":227},[182,440,158],{"class":202},[182,442,234],{"class":233},[182,444,158],{"class":202},[182,446,239],{"class":215},[182,448,242],{"class":202},[182,450,451],{"class":245},"\"read data from csv file...\"",[182,453,249],{"class":202},[182,455,456],{"class":184,"line":258},[182,457,255],{"class":202},[182,459,460],{"class":184,"line":265},[182,461,392],{"class":202},[172,463,466],{"className":174,"code":464,"filename":465,"language":177,"meta":178,"style":178},"public class ExcelFileImporter extends FileImporter {\n    @Override\n    public void readFile() {\n        System.out.println(\"read data from excel file...\");\n    }\n}\n","ExcelFileImporter.java",[111,467,468,483,489,501,520,524],{"__ignoreMap":178},[182,469,470,472,474,477,479,481],{"class":184,"line":185},[182,471,189],{"class":188},[182,473,195],{"class":188},[182,475,476],{"class":198}," ExcelFileImporter",[182,478,410],{"class":188},[182,480,199],{"class":198},[182,482,203],{"class":202},[182,484,485,487],{"class":184,"line":206},[182,486,419],{"class":202},[182,488,422],{"class":188},[182,490,491,493,495,497,499],{"class":184,"line":224},[182,492,209],{"class":188},[182,494,212],{"class":188},[182,496,317],{"class":215},[182,498,219],{"class":202},[182,500,203],{"class":202},[182,502,503,505,507,509,511,513,515,518],{"class":184,"line":252},[182,504,228],{"class":227},[182,506,158],{"class":202},[182,508,234],{"class":233},[182,510,158],{"class":202},[182,512,239],{"class":215},[182,514,242],{"class":202},[182,516,517],{"class":245},"\"read data from excel file...\"",[182,519,249],{"class":202},[182,521,522],{"class":184,"line":258},[182,523,255],{"class":202},[182,525,526],{"class":184,"line":265},[182,527,392],{"class":202},[172,529,532],{"className":174,"code":530,"filename":531,"language":177,"meta":178,"style":178},"public class WordFileImporter extends FileImporter {\n    @Override\n    public void readFile() {\n        System.out.println(\"read data from word file...\");\n    }\n}\n","WordFileImporter.java",[111,533,534,549,555,567,586,590],{"__ignoreMap":178},[182,535,536,538,540,543,545,547],{"class":184,"line":185},[182,537,189],{"class":188},[182,539,195],{"class":188},[182,541,542],{"class":198}," WordFileImporter",[182,544,410],{"class":188},[182,546,199],{"class":198},[182,548,203],{"class":202},[182,550,551,553],{"class":184,"line":206},[182,552,419],{"class":202},[182,554,422],{"class":188},[182,556,557,559,561,563,565],{"class":184,"line":224},[182,558,209],{"class":188},[182,560,212],{"class":188},[182,562,317],{"class":215},[182,564,219],{"class":202},[182,566,203],{"class":202},[182,568,569,571,573,575,577,579,581,584],{"class":184,"line":252},[182,570,228],{"class":227},[182,572,158],{"class":202},[182,574,234],{"class":233},[182,576,158],{"class":202},[182,578,239],{"class":215},[182,580,242],{"class":202},[182,582,583],{"class":245},"\"read data from word file...\"",[182,585,249],{"class":202},[182,587,588],{"class":184,"line":258},[182,589,255],{"class":202},[182,591,592],{"class":184,"line":265},[182,593,392],{"class":202},[172,595,598],{"className":174,"code":596,"filename":597,"language":177,"meta":178,"style":178},"public class Demo {\n    public static void main(String[] args) {\n        ExcelFileImporter excelFileImporter = new ExcelFileImporter();\n        excelFileImporter.importFile();\n\n        WordFileImporter wordFileImporter = new WordFileImporter();\n        wordFileImporter.importFile();\n    }\n}\n","Demo.java",[111,599,600,611,639,657,669,673,689,700,704],{"__ignoreMap":178},[182,601,602,604,606,609],{"class":184,"line":185},[182,603,189],{"class":188},[182,605,195],{"class":188},[182,607,608],{"class":198}," Demo",[182,610,203],{"class":202},[182,612,613,615,618,620,623,625,628,631,634,637],{"class":184,"line":206},[182,614,209],{"class":188},[182,616,617],{"class":188}," static",[182,619,212],{"class":188},[182,621,622],{"class":215}," main",[182,624,242],{"class":202},[182,626,627],{"class":188},"String",[182,629,630],{"class":202},"[]",[182,632,633],{"class":227}," args",[182,635,636],{"class":202},")",[182,638,203],{"class":202},[182,640,641,644,647,650,653,655],{"class":184,"line":224},[182,642,643],{"class":188},"        ExcelFileImporter",[182,645,646],{"class":227}," excelFileImporter ",[182,648,649],{"class":202},"=",[182,651,652],{"class":188}," new",[182,654,476],{"class":215},[182,656,320],{"class":202},[182,658,659,662,664,667],{"class":184,"line":252},[182,660,661],{"class":227},"        excelFileImporter",[182,663,158],{"class":202},[182,665,666],{"class":215},"importFile",[182,668,320],{"class":202},[182,670,671],{"class":184,"line":258},[182,672,262],{"emptyLinePlaceholder":261},[182,674,675,678,681,683,685,687],{"class":184,"line":265},[182,676,677],{"class":188},"        WordFileImporter",[182,679,680],{"class":227}," wordFileImporter ",[182,682,649],{"class":202},[182,684,652],{"class":188},[182,686,542],{"class":215},[182,688,320],{"class":202},[182,690,691,694,696,698],{"class":184,"line":279},[182,692,693],{"class":227},"        wordFileImporter",[182,695,158],{"class":202},[182,697,666],{"class":215},[182,699,320],{"class":202},[182,701,702],{"class":184,"line":299},[182,703,255],{"class":202},[182,705,706],{"class":184,"line":304},[182,707,392],{"class":202},[32,709,710,711,713],{},"Running ",[111,712,165],{}," prints:",[172,715,720],{"className":716,"code":718,"language":719,"meta":178},[717],"language-text","open file...\nread data from excel file...\nclose file...\nopen file...\nread data from word file...\nclose file...\n","text",[111,721,718],{"__ignoreMap":178},[723,724,725],"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 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}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);}",{"title":178,"searchDepth":206,"depth":206,"links":727},[728,729,730,734,735],{"id":29,"depth":206,"text":30},{"id":43,"depth":206,"text":44},{"id":63,"depth":206,"text":64,"children":731},[732,733],{"id":68,"depth":224,"text":69},{"id":83,"depth":224,"text":84},{"id":98,"depth":206,"text":99},{"id":169,"depth":206,"text":170},"The Template Method pattern fixes the steps of a task in a base class and lets subclasses fill in only the steps that differ. Explained with a worked Java example of importing CSV, Excel and Word files.","Importing CSV, Excel and Word files","md","Behavioral","lucide:layout-template",{},"\u002Flearn\u002Fdesign-patterns\u002Ftemplate-method","---\ntitle: Template Method\ngroup: Behavioral\nicon: lucide:layout-template\nsummary: 'A base class fixes the steps of a task, and subclasses fill in the steps that differ.'\ndescription: 'The Template Method pattern fixes the steps of a task in a base class and lets subclasses fill in only the steps that differ. Explained with a worked Java example of importing CSV, Excel and Word files.'\nexample: 'Importing CSV, Excel and Word files'\norder: 7\nsource: https:\u002F\u002Fgithub.com\u002FHaythamasalama\u002FdesignPattern\u002Ftree\u002Fmaster\u002Fsrc\u002FBehavioral\u002FTemplateMethod\n---\n\n## The idea\n\nSeveral classes often do the same task in the same order, with only one or two steps that differ. Importing a file always means opening it, reading it and closing it. Only the reading depends on the file type. If each importer writes all three steps, the shared steps are copied into every class.\n\nThe Template Method pattern puts the order of the steps in one method of a base class: the template method. Steps that are the same for everyone are written once, in the base class. Steps that differ are declared abstract, and each subclass fills them in.\n\nThe base class stays in control of the order. Subclasses can change a step, but not the sequence. This is sometimes called the Hollywood principle, \"don't call us, we'll call you\": the base class calls the subclass, not the other way round.\n\n## When to use it\n\n- Several classes run the same steps in the same order, and differ in only a few of them.\n- You want to stop subclasses from changing the order of a process, while letting them change its details.\n- You see the same code copied across sibling classes, with small changes.\n- You are writing a framework, and want its users to plug in their own code at fixed points.\n\n## Pros and cons\n\n### Pros\n\n- It reuses code: shared steps are written once, in the base class.\n- Extending the algorithm is easy: a new variant is a subclass that fills in the missing steps.\n- The order of the steps is fixed in one place.\n\n### Cons\n\n- It adds classes to the system: one subclass for every variant.\n- It relies on inheritance, so each object's variant is fixed when it is created. Strategy uses composition, and can be swapped at runtime.\n- The more steps a template has, the harder it is to see which ones a subclass may change.\n\n## The example\n\nThe example imports files of different types. Every import opens the file, reads it and closes it, and only the reading depends on the type.\n\n- **`FileImporter`**: the abstract class. `importFile()` is the template method. It is `final`, so subclasses can't change the order, and it calls `openFile()`, `readFile()` and `closeFile()`. Opening and closing are written once here, and `readFile()` is abstract.\n- **`CsvFileImporter`**, **`ExcelFileImporter`** and **`WordFileImporter`**: concrete classes. Each overrides only `readFile()`.\n- **`Demo`**: runs the Excel and Word importers. Both open and close the file in the same way, and differ only in the read step.\n\n## The code\n\n```java [FileImporter.java]\npublic abstract class FileImporter {\n    public void openFile() {\n        System.out.println(\"open file...\");\n    }\n\n    public void closeFile() {\n        System.out.println(\"close file...\");\n    }\n\n    abstract void readFile();\n\n    final public void importFile() {\n        this.openFile();\n        this.readFile();\n        this.closeFile();\n    }\n}\n```\n\n```java [CsvFileImporter.java]\npublic class CsvFileImporter extends FileImporter {\n    @Override\n    public void readFile() {\n        System.out.println(\"read data from csv file...\");\n    }\n}\n```\n\n```java [ExcelFileImporter.java]\npublic class ExcelFileImporter extends FileImporter {\n    @Override\n    public void readFile() {\n        System.out.println(\"read data from excel file...\");\n    }\n}\n```\n\n```java [WordFileImporter.java]\npublic class WordFileImporter extends FileImporter {\n    @Override\n    public void readFile() {\n        System.out.println(\"read data from word file...\");\n    }\n}\n```\n\n```java [Demo.java]\npublic class Demo {\n    public static void main(String[] args) {\n        ExcelFileImporter excelFileImporter = new ExcelFileImporter();\n        excelFileImporter.importFile();\n\n        WordFileImporter wordFileImporter = new WordFileImporter();\n        wordFileImporter.importFile();\n    }\n}\n```\n\nRunning `Demo` prints:\n\n```text\nopen file...\nread data from excel file...\nclose file...\nopen file...\nread data from word file...\nclose file...\n```\n",{"title":22,"description":736},{"loc":742},"https:\u002F\u002Fgithub.com\u002FHaythamasalama\u002FdesignPattern\u002Ftree\u002Fmaster\u002Fsrc\u002FBehavioral\u002FTemplateMethod","learn\u002Fdesign-patterns\u002Ftemplate-method","A base class fixes the steps of a task, and subclasses fill in the steps that differ.","ZAgEIBeWw8z51VxzINX4-mebYzQ98pMbJwuM5nJ9Iz8",[751,756,761,766,771,776,781,782],{"path":752,"title":753,"icon":754,"summary":755,"order":185},"\u002Flearn\u002Fdesign-patterns\u002Fchain-of-responsibility","Chain of Responsibility","lucide:link","Pass a request along a chain of handlers, where each one can deal with it or hand it to the next.",{"path":757,"title":758,"icon":759,"summary":760,"order":206},"\u002Flearn\u002Fdesign-patterns\u002Fcommand","Command","lucide:square-terminal","Turn a request into an object, so it can be passed around, queued, logged or undone.",{"path":762,"title":763,"icon":764,"summary":765,"order":224},"\u002Flearn\u002Fdesign-patterns\u002Fiterator","Iterator","lucide:list-ordered","Walk through the items of a collection one by one, without knowing how the collection stores them.",{"path":767,"title":768,"icon":769,"summary":770,"order":252},"\u002Flearn\u002Fdesign-patterns\u002Fobserver","Observer","lucide:bell","One object announces a change, and every object that subscribed to it hears about it.",{"path":772,"title":773,"icon":774,"summary":775,"order":258},"\u002Flearn\u002Fdesign-patterns\u002Fstate","State","lucide:toggle-left","An object changes its behaviour when its internal state changes, as if it had changed its class.",{"path":777,"title":778,"icon":779,"summary":780,"order":265},"\u002Flearn\u002Fdesign-patterns\u002Fstrategy","Strategy","lucide:shuffle","Put each way of doing a task in its own class, and choose which one to use while the program runs.",{"path":742,"title":22,"icon":740,"summary":748,"order":279},{"path":783,"title":784,"icon":785,"summary":786,"order":299},"\u002Flearn\u002Fdesign-patterns\u002Fvisitor","Visitor","lucide:footprints","Add new operations to a set of classes without changing them, by moving each operation into its own visitor.",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":788},"\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":790},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"8\" height=\"8\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M7 11v4a2 2 0 0 0 2 2h4\"\u002F>\u003Crect width=\"8\" height=\"8\" x=\"13\" y=\"13\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":792},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"\u002F>\u003Cpath d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":794},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m7 11l2-2l-2-2m4 6h4\"\u002F>\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":796},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 5h10m-10 7h10m-10 7h10M4 4h1v5M4 9h2m.5 11H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":798},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10.268 21a2 2 0 0 0 3.464 0m-10.47-5.674A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":800},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"9\" cy=\"12\" r=\"3\"\u002F>\u003Crect width=\"20\" height=\"14\" x=\"2\" y=\"5\" rx=\"7\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":802},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m18 14l4 4l-4 4m0-20l4 4l-4 4\"\u002F>\u003Cpath d=\"M2 18h1.973a4 4 0 0 0 3.3-1.7l5.454-8.6a4 4 0 0 1 3.3-1.7H22M2 6h1.972a4 4 0 0 1 3.6 2.2M22 18h-6.041a4 4 0 0 1-3.3-1.8l-.359-.45\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":804},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"\u002F>\u003Crect width=\"9\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"\u002F>\u003Crect width=\"5\" height=\"7\" x=\"16\" y=\"14\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":806},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16v-2.38C4 11.5 2.97 10.5 3 8c.03-2.72 1.49-6 4.5-6C9.37 2 10 3.8 10 5.5c0 3.11-2 5.66-2 8.68V16a2 2 0 1 1-4 0m16 4v-2.38c0-2.12 1.03-3.12 1-5.62c-.03-2.72-1.49-6-4.5-6C14.63 6 14 7.8 14 9.5c0 3.11 2 5.66 2 8.68V20a2 2 0 1 0 4 0m-4-3h4M4 13h4\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":808},"\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>",1793131417000]