<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3701737190756431503</id><updated>2026-04-06T03:18:11.062-04:00</updated><category term="Canada"/><category term="Delphi"/><category term="Delphi Programming"/><category term="Programming"/><category term="immigrant"/><category term="immigration"/><category term="Citizenship and Immigration Canada"/><category term="Object Pascal Programming"/><category term="Citizenship"/><category term="Citizenship Test"/><category term="Discover Canada"/><category term="Object-Oriented Programming"/><category term="Pascal"/><category term="Computers"/><category term="tips for immigrants"/><category term="Design Patterns"/><category term="Blogger"/><category term="Internet"/><category term="blog"/><category term="Bank"/><category term="Pascal Programming"/><category term="RBC"/><category term="banking"/><category term="investing"/><category term="Ontario"/><category term="SEO"/><category term="Search Engine Optimization"/><category term="Toronto"/><category term="CRA"/><category term="Cuba"/><category term="Google"/><category term="Royal Bank"/><category term="Royal Bank of Canada"/><category term="investment portfolio"/><category term="Algorithm"/><category term="Amazon"/><category term="Canada Revenue Agency"/><category term="Canadian Arctic Expedition"/><category term="Creational Patterns"/><category term="DUnit"/><category term="ETF"/><category term="ETFs"/><category term="IDE"/><category term="Income Tax"/><category term="MER"/><category term="Mint"/><category term="Royal Canadian Mint"/><category term="Sponsorship"/><category term="Sponsorship Canada"/><category term="Tangerine"/><category term="Taxes"/><category term="VBAL"/><category term="archived"/><category term="balanced portfolio"/><category term="coin"/><category term="nonimmigrant visas"/><category term="year 2013"/><category term="AdSense"/><category term="Behavioral Patterns"/><category term="Brick Platinum Card"/><category term="CIC"/><category term="Capital Markets"/><category term="Chequing"/><category term="Draft"/><category term="Dynadot"/><category term="ExchangeTraded Funds"/><category term="FEE"/><category term="FMF"/><category term="ICANN"/><category term="IMF"/><category term="ING DIRECT"/><category term="InfoLinks"/><category term="Online Banking"/><category term="Questrade"/><category term="RRSP"/><category term="SERVICE FEE"/><category term="Structural patterns"/><category term="TDD"/><category term="Template Method"/><category term="Test Driven Development"/><category term="The Brick"/><category term="US"/><category term="Unit testing"/><category term="VISA"/><category term="XML"/><category term="blog search engine"/><category term="credit card"/><category term="dash cam"/><category term="dash cams"/><category term="dashboard camera"/><category term="dashcam"/><category term="dashcams"/><category term="domain"/><category term="domain name registrar"/><category term="gold coin"/><category term="iterative"/><category term="recursion"/><category term="recursive"/><category term="silver coin"/><category term="visitor visas"/><category term="API"/><category term="Alberta"/><category term="Amazon Affiliates"/><category term="Application for Temporary Resident Visa"/><category term="Atom"/><category term="Backup"/><category term="Base64"/><category term="Best Buy"/><category term="Big-O"/><category term="Bing"/><category term="British Columbia"/><category term="Chase"/><category term="Cloud"/><category term="Condo"/><category term="DIY"/><category term="Day Trip"/><category term="Debit Card"/><category term="Ding"/><category term="Divorce"/><category term="Embarcadero"/><category term="FFmpeg"/><category term="Face value $1"/><category term="Face value $100"/><category term="FireMonkey"/><category term="Free Pascal"/><category term="Google AdSense"/><category term="Gource"/><category term="Government of Canada 10-Year Bond"/><category term="Government of Canada 2-Year Bond"/><category term="HMAC"/><category term="Hotel Reviews"/><category term="Hotels"/><category term="I-94"/><category term="I-94 Form"/><category term="IDERA"/><category term="Impark"/><category term="Indy"/><category term="Invitation Letter"/><category term="JPMorgan Chase Bank"/><category term="Lazarus"/><category term="Letter of Authority"/><category term="Letter of Invitation"/><category term="MD5"/><category term="Macros"/><category term="Manitoba"/><category term="Manulife"/><category term="Mintage 2500"/><category term="Mintage 40000"/><category term="Monthly Fee"/><category term="MultiProduct Rebate"/><category term="New Brunswick"/><category term="Newfoundland and Labrador"/><category term="No Foreign Currency Transaction Fee"/><category term="Northwest Territories"/><category term="Nova Scotia"/><category term="Nunavut"/><category term="Nunavut Territory"/><category term="Online Backup"/><category term="Online Storage"/><category term="Option C"/><category term="Option C Printout"/><category term="Owning"/><category term="PageRank"/><category term="Pascal Script"/><category term="Point Pelee"/><category term="Point Pelee National Park of Canada"/><category term="Prince Edward Island"/><category term="Privacy"/><category term="Provincial Tax"/><category term="Quebec"/><category term="RBC U.S. High Interest eSavings account"/><category term="RRSP transfer"/><category term="RSS"/><category term="Real Estate"/><category term="Renting"/><category term="Reviews"/><category term="SHA1"/><category term="SHA256"/><category term="Saskatchewan"/><category term="Savings account"/><category term="Scene Visa card"/><category term="Scene Visa card login"/><category term="ScotiaCard"/><category term="Scotiabank"/><category term="Shouldice"/><category term="Shouldice Hospital"/><category term="Singleton"/><category term="Source Code"/><category term="Sunlife"/><category term="Surtax"/><category term="Sync.com"/><category term="TFSA"/><category term="TTC"/><category term="Tangerine’s USD Savings Account"/><category term="Tax-Free Savings Account"/><category term="Technorati"/><category term="The Toronto Transit Commission"/><category term="The Wealthy Renter"/><category term="TopOfBlogs"/><category term="Toronto Transit Commission"/><category term="Transit"/><category term="Travel Canada"/><category term="Trip Canada"/><category term="TurboTax"/><category term="Twitter"/><category term="URL"/><category term="US cash"/><category term="USD"/><category term="VSB"/><category term="VSC"/><category term="Vanguard"/><category term="Visit Canada"/><category term="Windsor"/><category term="Xerox WorkCentre 6015"/><category term="Xerox WorkCentre 6015 printer"/><category term="Yahoo"/><category term="Yukon"/><category term="Yukon Territory"/><category term="backlinks"/><category term="black box"/><category term="blackbox"/><category term="blog directory"/><category term="bonds"/><category term="car park"/><category term="cartridges"/><category term="cold climate"/><category term="cold weather"/><category term="configure"/><category term="corporate bonds"/><category term="credit spread"/><category term="eBay"/><category term="factorial"/><category term="government bonds"/><category term="hernia"/><category term="hernia repair"/><category term="jobs"/><category term="money"/><category term="newcomers"/><category term="parking"/><category term="parking lot"/><category term="portfolio"/><category term="printer"/><category term="rebate"/><category term="refugees"/><category term="robbed by Impark"/><category term="sitemap"/><category term="society"/><category term="statement"/><category term="tag"/><category term="tag cloud"/><category term="thief company"/><category term="toner cartridges"/><category term="umbilical hernia"/><category term="umbilical hernia repair"/><category term="withholding tax"/><category term="yield spread"/><title type='text'>Yanniel&#39;s notes</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.yanniel.info/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/-/Delphi'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/search/label/Delphi'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/-/Delphi/-/Delphi?start-index=26&amp;max-results=25'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>32</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-8675293458518483991</id><published>2015-10-22T16:13:00.001-04:00</published><updated>2015-10-22T21:52:04.117-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Embarcadero"/><category scheme="http://www.blogger.com/atom/ns#" term="IDERA"/><title type='text'>IDERA’s intention for Embarcadero’s development tools</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
I just received the email below from IDERA\Embarcadero. Overall it means they plan on moving forward with Delphi and the other development tools in their portfolio.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I wanted to share the news in case you haven’t heard.&lt;br /&gt;
_______________________________________________________________________________________________&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Customer and Partner Welcome from IDERA&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Dear Sir/Madam,&lt;br /&gt;
&lt;br /&gt;
I am Randy Jacops, the CEO of IDERA, Inc. You likely saw the press announcement of IDERA’s recent acquisition of Embarcadero Technologies. Here is a link to the announcement if you have not seen it.&lt;br /&gt;
&lt;br /&gt;
We welcome you to the IDERA family and look forward to continuing Embarcadero’s history of market leading products for data professionals and developers. I’m writing this letter to introduce IDERA and explain why we are excited to own Embarcadero.&lt;br /&gt;
&lt;br /&gt;
IDERA serves over 10,000 customers around the world with performance monitoring solutions for databases, applications and technology infrastructure. We believe database professionals have an outsize impact on overall technology performance and describe our focus as database-centric. Our products enable rapid identification and remediation of performance problems across the technology stack as well as providing unique security and compliance capability.&lt;br /&gt;
&lt;br /&gt;
I became CEO in 2013 and during my tenure have focused the company on long-term customer relationships built on innovation, quality, and ease of use. I strongly believe a successful software company starts with a focus on driving customer success via:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; High quality software – complete testing with significant automated code coverage&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Ease of use – simplified user experience, particularly the install/upgrade process&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Application speed – minimal wait time, robust scalability, and real-time analytics&lt;br /&gt;
&lt;br /&gt;
A software company that delivers these metrics will have generally happy customers. Delivering prioritized innovation and features on a reliable schedule advances the relationship from generally happy to customer success. IDERA prioritizes investment to reflect these goals and we will apply the same philosophy to Embarcadero’s products.&lt;br /&gt;
&lt;br /&gt;
As you know, Embarcadero has two unique product families: 1) heterogeneous database modeling, administration, and performance and 2) application development solutions for multiple platforms. Over the years, Embarcadero also built a roster of over 10,000 customers and millions of users, serving nearly the entire Global 2000. Embarcadero operates globally with offices and partners in nearly every major country.&lt;br /&gt;
&lt;br /&gt;
Embarcadero’s database modeling, administration, and performance tools complement IDERA’s products with minimal overlap in functionality and business purpose. By combining the two businesses, we will offer data professionals a comprehensive solution to manage, deploy, and protect data across the company. We will seek customer feedback on integration between the solutions to ensure we adhere to our core product values of simplicity of use, quality, and scalability.&lt;br /&gt;
&lt;br /&gt;
For Embarcadero’s development tools, we acknowledge this is a new opportunity for IDERA. I have seen some chatter on our community forums and received direct questions from customers on IDERA’s intentions for the product line. I wish to emphasize the tremendous value we perceive in development tools. As applications proliferate across multiple channels and platforms, the need for tools to build the next generation of applications will soar. Concepts such as the Internet of Things or proximity awareness in applications did not exist several years ago. Today, everybody recognizes the opportunity in building applications for equipment that simplifies and advances society. We believe the winners in the application development market will focus on the developer and differentiate with speed to market, ease of use, and pace of change. All of these things perfectly align with IDERA’s view of product and customer success.&lt;br /&gt;
&lt;br /&gt;
To that end, we formed a new leadership team that will focus exclusively on Embarcadero’s development tools and growing the business via innovations and opportunistic M&amp;amp;A. Atanas Popov, a longtime colleague of mine, has joined Embarcadero to lead the team. Atanas will focus his attention on growing the business and investing to attract more customers to our solutions. We believe there is significant opportunity in Embarcadero’s development tools and we look forward to working with you to prioritize our investments.&lt;br /&gt;
&lt;br /&gt;
Finally, Embarcadero invested for years to build a robust and reliable reseller/partner network. Many companies aspire to building such a network but the time and effort required eventually discourages most. However, if a company perseveres and delivers a healthy reseller and partner business, the impact and potential is significant. Embarcadero has dozens of active and significant global partners. Maintaining a healthy reseller/partner network requires more and better product and a steady stream of potential customers interested in buying. We expect to introduce IDERA’s broader product family to Embarcadero’s partners and also plan to leverage IDERA’s talented marketing team to refine messaging and advance dialogue with prospects. We believe some modest changes and investment will expand the universe of opportunities for our partners who serve a global customer base.&lt;br /&gt;
&lt;br /&gt;
From an ongoing communication standpoint, we believe in publishing our product roadmaps to active customers and maintaining dialogue with customers interested in contributing. We believe user communities deliver significant customer value and will continue investing appropriately. We also believe that change facilitates innovation and increases value for our customers. We will remain committed to these principles and look forward to working with you to improve every day and help you capture expected value.&lt;br /&gt;
&lt;br /&gt;
If you have questions, please feel free to contact me directly (randy.jacops@idera.com). With over 20,000 customers, it’s not practical to maintain a direct dialogue with every customer, but we will respond to questions. Most importantly, we will communicate future product roadmap reviews, webinars, and related content you will find interesting. I encourage you to participate in all these sessions to ensure a mutually valuable relationship.&lt;br /&gt;
&lt;br /&gt;
Thank you for your business and I look forward to the future.&lt;br /&gt;
&lt;br /&gt;
Regards,&lt;br /&gt;
&lt;br /&gt;
Randy Jacops&lt;br /&gt;
CEO, IDERA, Inc.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/8675293458518483991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2015/10/ideras-intention-for-embarcadero-development-tools.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8675293458518483991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8675293458518483991'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2015/10/ideras-intention-for-embarcadero-development-tools.html' title='IDERA’s intention for Embarcadero’s development tools'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-8015288562881500874</id><published>2014-09-11T22:19:00.000-04:00</published><updated>2014-09-12T00:13:59.250-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="FFmpeg"/><category scheme="http://www.blogger.com/atom/ns#" term="Free Pascal"/><category scheme="http://www.blogger.com/atom/ns#" term="Gource"/><category scheme="http://www.blogger.com/atom/ns#" term="Lazarus"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>The source code history of Free Pascal and Lazarus visualized with Gource</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;a href=&quot;https://code.google.com/p/gource/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;Gource&lt;/b&gt;&lt;/a&gt; is a software version control visualization tool. I thought it would be fun to visualize &lt;b&gt;Delphi&lt;/b&gt;’s source code with &lt;b&gt;Gource&lt;/b&gt;, but that is not possible for obvious reasons. So, I decided to try-out &lt;b&gt;Delphi&lt;/b&gt;’s cousins: &lt;b&gt;&lt;a href=&quot;http://www.freepascal.org/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Free Pascal&lt;/a&gt;&lt;/b&gt; and &lt;b&gt;&lt;a href=&quot;http://www.lazarus.freepascal.org/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Lazarus&lt;/a&gt;&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
I checked-out the respective code bases and ran them through &lt;b&gt;Gource&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Below are the &lt;b&gt;Gource&lt;/b&gt; commands I used:&lt;/div&gt;
&lt;br /&gt;
&lt;code&gt;
gource -1280x720 -o C:\\gource\\fpc.ppm -s 0.01 --hide dirnames,filenames,progress,mouse C:\\gource\\fpc&lt;br /&gt;
&lt;br /&gt;
gource -1280x720 -o&amp;nbsp; C:\\gource\\lazarus.ppm -s 0.01 --hide dirnames,filenames,progress,mouse C:\\gource\\lazarus&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;Gource&lt;/b&gt; shows the filenames and directories of the source code by default; still, I decided to hide them in these videos, because they were overlapping. You can play more with &lt;b&gt;Gource&lt;/b&gt;, &lt;b&gt;FPC &lt;/b&gt;and &lt;b&gt;Lazarus &lt;/b&gt;on your own :-) For a comprehensive list of the command line options and arguments of &lt;b&gt;Gource&lt;/b&gt; click &lt;a href=&quot;https://github.com/acaudwell/Gource/blob/master/README&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;HERE&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The above &lt;i&gt;gource&lt;/i&gt; calls create two files: &lt;i&gt;fpc.ppm&lt;/i&gt; and &lt;i&gt;lazarus.ppm&lt;/i&gt;. I guess these are some kind of uncompressed video format. The files were huge: ~60GB and ~100GB respectively.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Then, I used &lt;a href=&quot;https://www.ffmpeg.org/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;FFmpeg&lt;/b&gt;&lt;/a&gt; to encode the above .ppm files into .avi files. The &lt;b&gt;FFmpeg&lt;/b&gt; commands are below:&lt;/div&gt;
&lt;br /&gt;
&lt;code&gt;
ffmpeg -y -r 60 -f image2pipe -vcodec ppm -i C:\\gource\\fpc.ppm -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -crf 1 -threads 0 -bf 0 C:\\gource\\fpc.x264.avi&lt;br /&gt;
&lt;br /&gt;
ffmpeg -y -r 60 -f image2pipe -vcodec ppm -i C:\\gource\\lazarus.ppm -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -crf 1 -threads 0 -bf 0 C:\\gource\\lazarus.x264.avi&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Finally, I uploaded &lt;i&gt;fpc.x264.avi&lt;/i&gt; and &lt;i&gt;lazarus.x264.avi&lt;/i&gt; to YouTube. You can see them below:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Free Pascal source code history visualized with Gource&amp;nbsp; &lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/NauKjJ6jvJc&quot; width=&quot;560&quot;&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Lazarus source code history visualized with Gource&amp;nbsp; &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/RnE51nmyZj4&quot; width=&quot;560&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
If you liked this post; please, show your appreciation but clicking the &lt;span style=&quot;color: orange;&quot;&gt;&lt;b&gt;Google Plus (G+)&lt;/b&gt;&lt;/span&gt; button at the beginning of the article. Thanks!&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/8015288562881500874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2014/09/Free-Pascal-and-Lazarus-visualized-with-Gource.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8015288562881500874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8015288562881500874'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2014/09/Free-Pascal-and-Lazarus-visualized-with-Gource.html' title='The source code history of Free Pascal and Lazarus visualized with Gource'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-2577127087294627350</id><published>2014-04-04T22:27:00.000-04:00</published><updated>2014-04-04T23:19:48.095-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Algorithm"/><category scheme="http://www.blogger.com/atom/ns#" term="Base64"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="HMAC"/><category scheme="http://www.blogger.com/atom/ns#" term="MD5"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="SHA1"/><category scheme="http://www.blogger.com/atom/ns#" term="SHA256"/><title type='text'>HMAC functions in Delphi (HMAC_SHA256, HMAC_SHA1)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
I came across &lt;b&gt;HMAC &lt;/b&gt;(&lt;a href=&quot;http://en.wikipedia.org/wiki/Hash-based_message_authentication_code&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Hash-based message authentication code&lt;/a&gt;) functions when developing a RESTful client application in Delphi. The RESTful Web Service API required me to send &lt;b&gt;HMAC_SHA256&lt;/b&gt; signatures (&lt;i&gt;Base64 &lt;/i&gt;encoded) with each HTTP request.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;b&gt;HMAC &lt;/b&gt;functions take two parameters: a &lt;b&gt;key &lt;/b&gt;and a &lt;b&gt;message&lt;/b&gt;. The purpose of the &lt;b&gt;HMAC &lt;/b&gt;function is to authenticate the message and guarantee the data integrity of the message.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
The cryptographic strength of the &lt;b&gt;HMAC &lt;/b&gt;function lies on the underlying hashing function that it uses: &lt;b&gt;MD5&lt;/b&gt;, &lt;b&gt;SHA1&lt;/b&gt;, &lt;b&gt;SHA256&lt;/b&gt;, etc.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
So, these functions are usually are termed &lt;b&gt;HMAC_SHA256&lt;/b&gt;, &lt;b&gt;HMAC_SHA1&lt;/b&gt;, &lt;b&gt;HMAC_MD5&lt;/b&gt; to connote the core hashing function being used.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
The outcome of a &lt;b&gt;HMAC &lt;/b&gt;function is basically an array of bytes, but it is usually represented as a hexadecimal string or encoded as a &lt;i&gt;Base64 &lt;/i&gt;string. (The RESTful Web Service API needed the &lt;i&gt;Base64 &lt;/i&gt;encoded output).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I Googled around for a bit, but I didn’t get a clean implementation of &lt;b&gt;HMAC_SHA256&lt;/b&gt; in Delphi (encoded as &lt;i&gt;Base64&lt;/i&gt;). I glued together the pieces from some questions on StackOverflow and coded an Indy based implementation that uses &lt;i&gt;generics &lt;/i&gt;to specify the core hashing function.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Brief description: I created a helper class called &lt;b&gt;THMACUtils&lt;/b&gt;. Note that this class uses generics to indicate the hashing algorithm (&lt;b&gt;TIdHMACSHA256&lt;/b&gt;, &lt;b&gt;TIdHMACSHA1&lt;/b&gt;). Three functions are provided:&amp;nbsp; the main thing happens in the &lt;b&gt;HMAC(...)&lt;/b&gt; function; &lt;b&gt;HMAC_HexStr(...)&lt;/b&gt; and &lt;b&gt;HMAC_Base64(...) &lt;/b&gt;are simply decorations of the output.&lt;br /&gt;
&lt;code&gt;
&lt;/code&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;unit HMAC;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;code&gt;interface&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; System.SysUtils,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; EncdDecd,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; IdHMAC,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; IdSSLOpenSSL,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; IdHash;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;code&gt;type&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; THMACUtils&amp;lt;T: TIdHMAC, constructor&amp;gt; = class&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class function HMAC(aKey, aMessage: RawByteString): TBytes;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class function HMAC_HexStr(aKey, aMessage: RawByteString): RawByteString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class function HMAC_Base64(aKey, aMessage: RawByteString): RawByteString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;code&gt;class function THMACUtils&amp;lt;T&amp;gt;.HMAC(aKey, aMessage: RawByteString): TBytes;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; _HMAC: T;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; if not IdSSLOpenSSL.LoadOpenSSLLibrary then Exit;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; _HMAC:= T.Create;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _HMAC.Key := BytesOf(aKey);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= _HMAC.HashValue(BytesOf(aMessage));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _HMAC.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;code&gt;class function THMACUtils&amp;lt;T&amp;gt;.HMAC_HexStr(aKey, aMessage: RawByteString): RawByteString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; I: Byte;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= &#39;0x&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; for I in HMAC(aKey, aMessage) do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= Result + IntToHex(I, 2);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;code&gt;class function THMACUtils&amp;lt;T&amp;gt;.HMAC_Base64(aKey, aMessage: RawByteString): RawByteString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; _HMAC: TBytes;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; _HMAC:= HMAC(aKey, aMessage);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= EncodeBase64(_HMAC, Length(_HMAC));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;code&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;code&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;u&gt;Below there’s an example of how to use the &lt;b&gt;THMACUtils &lt;/b&gt;class.&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;
program HMACSample;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;{$R *.res}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;&amp;nbsp; System.SysUtils,&lt;br /&gt;&amp;nbsp; HMAC,&lt;br /&gt;&amp;nbsp; IdHMACSHA1,&lt;br /&gt;&amp;nbsp; IdHashMessageDigest;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(&#39;HMAC_SHA1(&quot;key&quot;, &quot;message&quot;)&#39;#9#9&#39;= &#39;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(THMACUtils&amp;lt;TIdHMACSHA1&amp;gt;.HMAC_HexStr(&#39;key&#39;, &#39;message&#39; ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(&#39;HMAC_SHA256(&quot;key&quot;, &quot;message&quot;)&#39;#9#9&#39;= &#39;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(THMACUtils&amp;lt;TIdHMACSHA256&amp;gt;.HMAC_HexStr(&#39;key&#39;, &#39;message&#39; ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(&#39;HMAC_SHA1_Base64(&quot;key&quot;, &quot;message&quot;)&#39;#9&#39;= &#39;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(THMACUtils&amp;lt;TIdHMACSHA1&amp;gt;.HMAC_Base64(&#39;key&#39;, &#39;message&#39; ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(&#39;HMAC_SHA256_Base64(&quot;key&quot;, &quot;message&quot;)&#39;#9&#39;= &#39;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(THMACUtils&amp;lt;TIdHMACSHA256&amp;gt;.HMAC_Base64(&#39;key&#39;, &#39;message&#39; ));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Readln;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; on E: Exception do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(E.ClassName, &#39;: &#39;, E.Message);&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;u&gt;The console application above looks like this: &lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8S1OVlTbLaaciPmqJyLDx53XEu3RUMFr1trU3RTMiQ7ro8zQyFDaQoy8f546rPmjXakAFz1qIIgMVPNHc6ocUs8QNNrxsHaa9li12C99pLmCnWUGLUg6a9SClK_Qz0kox2Dnl8Av0hho/s1600/HMAC+Sample+Application+Delphi.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img alt=&quot;HMAC Sample Application Delphi&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8S1OVlTbLaaciPmqJyLDx53XEu3RUMFr1trU3RTMiQ7ro8zQyFDaQoy8f546rPmjXakAFz1qIIgMVPNHc6ocUs8QNNrxsHaa9li12C99pLmCnWUGLUg6a9SClK_Qz0kox2Dnl8Av0hho/s1600/HMAC+Sample+Application+Delphi.jpg&quot; height=&quot;252&quot; title=&quot;HMAC Sample Application Delphi&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;HMAC Sample Application Delphi&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/2577127087294627350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2014/04/hmac-functions-in-delphi.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/2577127087294627350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/2577127087294627350'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2014/04/hmac-functions-in-delphi.html' title='HMAC functions in Delphi (HMAC_SHA256, HMAC_SHA1)'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8S1OVlTbLaaciPmqJyLDx53XEu3RUMFr1trU3RTMiQ7ro8zQyFDaQoy8f546rPmjXakAFz1qIIgMVPNHc6ocUs8QNNrxsHaa9li12C99pLmCnWUGLUg6a9SClK_Qz0kox2Dnl8Av0hho/s72-c/HMAC+Sample+Application+Delphi.jpg" height="72" width="72"/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-8200311418490848656</id><published>2013-01-13T20:21:00.003-05:00</published><updated>2013-01-13T22:19:36.985-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="FireMonkey"/><title type='text'>Enabling TLang to handle more than 17 translations: a workaround for a regression bug in Delphi XE3 </title><content type='html'>I recently had to localize a &lt;b&gt;FireMonkey &lt;/b&gt;application and for that I aimed to use the &lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/XE3/en/FMX.Types.TLang&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;TLang&lt;/a&gt; component. With &lt;b&gt;TLang &lt;/b&gt;you can define a collection of native strings to be localized and the corresponding translations to a particular language. To my surprise the component was allowing to store a maximum of 17 translations for the whole application. So, what about the other strings that need localization?&lt;br /&gt;
&lt;br /&gt;
It seems there’s a regression issue from &lt;b&gt;Delphi XE2&lt;/b&gt; to &lt;b&gt;Delphi XE3&lt;/b&gt; that is preventing &lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;TLang &lt;/b&gt;&lt;/span&gt;to store more than 1&lt;b&gt;7&lt;/b&gt; translations. You can even find an entry for this in &lt;a href=&quot;http://qc.embarcadero.com/wc/qcmain.aspx?d=109678&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Embarcadero Quality Central&lt;/a&gt;, for which no workaround or fix has been provided up to this date.&lt;br /&gt;
&lt;br /&gt;
I found a programmatic workaround for this issue. Basically, the native strings and the translations could be loaded from text files in which each line will have the form:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;NativeString1=Translation1&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;NativeString2=Translation2&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;NativeString3=Translation3&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;…………&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;NativeStringN=TranslationN&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You will need one file containing the native strings and the translations per language. These files can contain as many lines as you which (certainly more than 17). In order to load those files into an existing &lt;b&gt;TLang &lt;/b&gt;component you can use the function below:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;procedure LoadTranslationsFromFile(aLangCode: string; aFileName: string; aLang: TLang);&lt;br /&gt;var&lt;br /&gt;&amp;nbsp; Translations: TStrings;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; if (aLangCode &amp;lt;&amp;gt; &#39;&#39;) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (FileExists(aFileName)) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (Assigned(aLang)) then&lt;br /&gt;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Translations:= TStringList.Create;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Translations.LoadFromFile(aFileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aLang.Resources.AddObject(aLangCode, Translations);&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
For an example of how to use such function see below:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; LoadTranslationsFromFile(&#39;ES&#39;, &#39;C:\Temp\Lang_Test_ES.txt&#39;, Lang1);&lt;br /&gt;&amp;nbsp; LoadTranslationsFromFile(&#39;EN&#39;, &#39;C:\Temp\Lang_Test_EN.txt&#39;, Lang1);&lt;br /&gt;end;&lt;/code&gt; &lt;br /&gt;
&lt;br /&gt;
Hopefully this bug will be fixed in the near future; but meanwhile you can use this workaround to handle more than 17 translations with the &lt;b&gt;TLang &lt;/b&gt;component.&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/8200311418490848656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2013/01/TLang-cannot-handle-more-than-17-translations-workaround-for-regression-issue-in-Delphi-XE3.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8200311418490848656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8200311418490848656'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2013/01/TLang-cannot-handle-more-than-17-translations-workaround-for-regression-issue-in-Delphi-XE3.html' title='Enabling TLang to handle more than 17 translations: a workaround for a regression bug in Delphi XE3 '/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-4944218353808619514</id><published>2012-12-17T10:47:00.002-05:00</published><updated>2013-01-13T22:19:26.631-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Behavioral Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="DUnit"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="Template Method"/><category scheme="http://www.blogger.com/atom/ns#" term="Test Driven Development"/><title type='text'>Refactoring to patterns. Yet another TDD example coded in Delphi</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Long overdue here is my second article about Test Driven Development (TDD) in Delphi. This is a continuation of &lt;a href=&quot;http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html&quot; target=&quot;_blank&quot;&gt;TDD in Delphi: The Basics&lt;/a&gt;, another post that I wrote a few months earlier.&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I would like to focus in a particular step within the TDD cycle: refactoring the code. Refactoring means optimizing, cleaning, shortening, beautifying, styling (put your own word here) the code without breaking the functionality; that is, without breaking your unit tests.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&amp;nbsp; &lt;br /&gt;
By having unit tests in place before refactoring, you guarantee that the changes to the code are safe. Refactoring can introduce bugs. To avoid those bugs you need your unit tests in place. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Refactoring can introduce something else: refactoring can introduce design patterns into your code. That means you don’t have to introduce the design patterns up-front, since your code can evolve from a “very rustic implementation” to a “pattern oriented implementation”. This is referred as “refactoring to patterns”. If you are interested on the topic, I advise you to read &lt;a href=&quot;http://www.amazon.com/gp/product/0321213351/ref=as_li_tf_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321213351&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Refactoring To Patterns by Joshua Kerievsky&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I’ll take the chess game as the base to my example. For simplicity, I’ll just refer to a couple of pieces: the knight and the bishop. In this example, I will just focus in refactoring some code with unit tests already in place. A detailed walk-through for the TDD cycle can be found in my &lt;a href=&quot;http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html&quot; target=&quot;_blank&quot;&gt;previous article&lt;/a&gt;, which is also based on the chess game.&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&amp;nbsp;&amp;nbsp; &lt;br /&gt;
The code is easy enough to be self-explanatory: basically, there is a class hierarchy in which &lt;b&gt;TPiece&lt;/b&gt; is the base class from which &lt;b&gt;TKnight &lt;/b&gt;and &lt;b&gt;TBishop &lt;/b&gt;derive. Take a quick look:&lt;/div&gt;
&lt;br /&gt;
&lt;code&gt;
unit ChessGame;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TPiece = class&lt;br /&gt;&amp;nbsp;private&lt;br /&gt;&amp;nbsp;&amp;nbsp; FX,&lt;br /&gt;&amp;nbsp;&amp;nbsp; FY: Byte;&lt;br /&gt;&amp;nbsp;public&lt;br /&gt;&amp;nbsp;&amp;nbsp; constructor Create(aX, aY: Integer);&lt;br /&gt;&amp;nbsp;&amp;nbsp; function IsWithinBoard(aX, aY: Integer): Boolean;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TBishop = class (TPiece)&lt;br /&gt;&amp;nbsp;public&lt;br /&gt;&amp;nbsp;&amp;nbsp; function CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TKnight = class(TPiece)&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TPiece }&lt;br /&gt;&lt;br /&gt;constructor TPiece.Create(aX, aY: Integer);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; inherited Create;&lt;br /&gt;&amp;nbsp; // TODO: check that this assignment is valid.&lt;br /&gt;&amp;nbsp; // Not now, ok? :-)&lt;br /&gt;&amp;nbsp; FX:= aX;&lt;br /&gt;&amp;nbsp; FY:= aY;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPiece.IsWithinBoard(aX, aY: Integer): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= (aX &amp;gt; 0) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aX &amp;lt; 9) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;gt; 0) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;lt; 9);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TKnight }&lt;br /&gt;&lt;br /&gt;function TKnight.isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp; x_diff,&lt;br /&gt;&amp;nbsp; y_diff: Integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; x_diff:= abs(aX - FX) ;&lt;br /&gt;&amp;nbsp; y_diff:= abs(aY - FY) ;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Result:= ((x_diff = 2) and (y_diff = 1))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; or&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((y_diff = 2) and (x_diff = 1));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TKnight.CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= IsWithinBoard(aX, aY) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsValidMove(aX, aY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TBishop }&lt;br /&gt;&lt;br /&gt;function TBishop.isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= abs(aX - FX) = abs(aY - FY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TBishop.CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= IsWithinBoard(aX, aY) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsValidMove(aX, aY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;b&gt;/////////////////////////////////////////////&lt;/b&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
unit TestChessGame;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;&amp;nbsp; TestFramework, ChessGame;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&amp;nbsp; // Test methods for class TPiece&lt;br /&gt;&amp;nbsp; TestTPiece = class(TTestCase)&lt;br /&gt;&amp;nbsp; strict private&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FPiece: TPiece;&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure SetUp; override;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TearDown; override;&lt;br /&gt;&amp;nbsp; published&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestIsWithinBoard;&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; // Test methods for class TBishop&lt;br /&gt;&amp;nbsp; TestTBishop = class(TTestCase)&lt;br /&gt;&amp;nbsp; strict private&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FBishop: TBishop;&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure SetUp; override;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TearDown; override;&lt;br /&gt;&amp;nbsp; published&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestCanMoveTo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestisValidMove;&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; // Test methods for class TKnight&lt;br /&gt;&amp;nbsp; TestTKnight = class(TTestCase)&lt;br /&gt;&amp;nbsp; strict private&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FKnight: TKnight;&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure SetUp; override;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TearDown; override;&lt;br /&gt;&amp;nbsp; published&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestCanMoveTo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestisValidMove;&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;procedure TestTPiece.SetUp;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FPiece := TPiece.Create(4, 4);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTPiece.TearDown;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FPiece.Free;&lt;br /&gt;&amp;nbsp; FPiece := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTPiece.TestIsWithinBoard;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; //Test trivial (normal) workflow&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(4, 4));&lt;br /&gt;&lt;br /&gt;&amp;nbsp; //Tests boundaries&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(1, 1));&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(1, 8));&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(8, 1));&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(8, 8));&lt;br /&gt;&lt;br /&gt;&amp;nbsp; //Test beyond the boundaries&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(3, 15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(3, -15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(15, 3));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(15, 15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(15, -15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(-15, 3));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(-15, 15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(-15, -15));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTBishop.SetUp;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FBishop := TBishop.Create(4, 4);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTBishop.TearDown;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FBishop.Free;&lt;br /&gt;&amp;nbsp; FBishop := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTBishop.TestCanMoveTo;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; // Hey developer, indulge me here: believe&lt;br /&gt;&amp;nbsp; // that I fully wrote the code for this&lt;br /&gt;&amp;nbsp; // test already before writing anything else.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTBishop.TestisValidMove;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; // Hey developer, indulge me here: believe&lt;br /&gt;&amp;nbsp; // that I fully wrote the code for this&lt;br /&gt;&amp;nbsp; // test already before writing anything else.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTKnight.SetUp;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FKnight := TKnight.Create(4, 4);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTKnight.TearDown;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FKnight.Free;&lt;br /&gt;&amp;nbsp; FKnight := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTKnight.TestCanMoveTo;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; // Hey developer, indulge me here: believe&lt;br /&gt;&amp;nbsp; // that I fully wrote the code for this&lt;br /&gt;&amp;nbsp; // test already before writing anything else.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTKnight.TestisValidMove;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; // Hey developer, indulge me here: believe&lt;br /&gt;&amp;nbsp; // that I fully wrote the code for this&lt;br /&gt;&amp;nbsp; // test already before writing anything else.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;initialization&lt;br /&gt;&amp;nbsp; // Register any test cases with the test runner&lt;br /&gt;&amp;nbsp; RegisterTest(TestTPiece.Suite);&lt;br /&gt;&amp;nbsp; RegisterTest(TestTBishop.Suite);&lt;br /&gt;&amp;nbsp; RegisterTest(TestTKnight.Suite);&lt;br /&gt;end.&lt;/code&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Note that the method &lt;b&gt;CanMoveTo &lt;/b&gt;is duplicated in both &lt;b&gt;TKnight&amp;nbsp; &lt;/b&gt;and &lt;b&gt;TBishop&lt;/b&gt;; that’s not nice isn’t it? In order to fix this, we can pull-up the &lt;b&gt;CanMoveTo &lt;/b&gt;method to the &lt;b&gt;TPiece &lt;/b&gt;base class. Note this now: the &lt;b&gt;CanMoveTo &lt;/b&gt;has now become a “&lt;a href=&quot;http://www.yanniel.info/2011/06/template-method-design-pattern-delphi.html&quot; target=&quot;_blank&quot;&gt;template method&lt;/a&gt;”; because is a general algorithm applicable to all kind of chess pieces (&lt;b&gt;TKnight &lt;/b&gt;,&lt;b&gt;TBishop&lt;/b&gt;, etc) .&lt;br /&gt;
&lt;br /&gt;
This general algorithm has deferred some steps to be implemented in the subclasses; I mean, the &lt;b&gt;isValidMove &lt;/b&gt;method is still coded in the subclasses. Isn’t this a beauty?&amp;nbsp; You have now refactored your code and when doing so, you have introduced the Template Method Design Pattern.&lt;br /&gt;
&lt;br /&gt;
What’s even best, (don’t forget this because it is a key part): is that we can guarantee that our fancy refactoring didn’t break our pre-existing functionality. Why? Because we had unit tests in place written a long time ago. Writing unit test from the beginning gives a huge peace of mind to the developer :-) See the new refactored code below:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
unit ChessGameRefactored;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TPiece = class&lt;br /&gt;&amp;nbsp;private&lt;br /&gt;&amp;nbsp;&amp;nbsp; FX,&lt;br /&gt;&amp;nbsp;&amp;nbsp; FY: Byte;&lt;br /&gt;&amp;nbsp;public&lt;br /&gt;&amp;nbsp;&amp;nbsp; constructor Create(aX, aY: Integer);&lt;br /&gt;&amp;nbsp;&amp;nbsp; function IsWithinBoard(aX, aY: Integer): Boolean;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; function CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean; virtual; abstract;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TBishop = class (TPiece)&lt;br /&gt;&amp;nbsp;public&lt;br /&gt;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean; override;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TKnight = class(TPiece)&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean; override;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TPiece }&lt;br /&gt;&lt;br /&gt;constructor TPiece.Create(aX, aY: Integer);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; inherited Create;&lt;br /&gt;&amp;nbsp; // TODO: check that this assignment is valid.&lt;br /&gt;&amp;nbsp; // Not now, ok? :-)&lt;br /&gt;&amp;nbsp; FX:= aX;&lt;br /&gt;&amp;nbsp; FY:= aY;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPiece.IsWithinBoard(aX, aY: Integer): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= (aX &amp;gt; 0) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aX &amp;lt; 9) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;gt; 0) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;lt; 9);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPiece.CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= IsWithinBoard(aX, aY) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsValidMove(aX, aY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TKnight }&lt;br /&gt;&lt;br /&gt;function TKnight.isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp; x_diff,&lt;br /&gt;&amp;nbsp; y_diff: Integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; x_diff:= abs(aX - FX) ;&lt;br /&gt;&amp;nbsp; y_diff:= abs(aY - FY) ;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Result:= ((x_diff = 2) and (y_diff = 1))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; or&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((y_diff = 2) and (x_diff = 1));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TBishop }&lt;br /&gt;&lt;br /&gt;function TBishop.isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= abs(aX - FX) = abs(aY - FY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Conclusion, in addition to all the cool things of TDD there’s the possibility of refining your design not up-front, but when refactoring your code. Design patterns can be introduced at any time and we know that such introduction, if late, is not going to break our logic, because we have unit tests in place to prevent that from happening.&lt;br /&gt;
&lt;br /&gt;
Some related reading below:&lt;/div&gt;
&lt;a href=&quot;http://www.amazon.com/gp/product/0321213351/ref=as_li_tf_il?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321213351&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0321213351&amp;amp;Format=_SL160_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20&quot; /&gt;&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0321213351&quot; style=&quot;border: none !important; margin: 0px !important;&quot; width=&quot;1&quot; /&gt;

&lt;a href=&quot;http://www.amazon.com/gp/product/0321146530/ref=as_li_tf_il?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321146530&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0321146530&amp;amp;Format=_SL160_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20&quot; /&gt;&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0321146530&quot; style=&quot;border: none !important; margin: 0px !important;&quot; width=&quot;1&quot; /&gt;

&lt;a href=&quot;http://www.amazon.com/gp/product/0201633612/ref=as_li_tf_il?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0201633612&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0201633612&amp;amp;Format=_SL160_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20&quot; /&gt;&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201633612&quot; style=&quot;border: none !important; margin: 0px !important;&quot; width=&quot;1&quot; /&gt;

&lt;a href=&quot;http://www.amazon.com/gp/product/0596007124/ref=as_li_tf_il?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596007124&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0596007124&amp;amp;Format=_SL160_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20&quot; /&gt;&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0596007124&quot; style=&quot;border: none !important; margin: 0px !important;&quot; width=&quot;1&quot; /&gt;

&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/4944218353808619514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2012/12/refactoring-to-patterns-in-delphi.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4944218353808619514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4944218353808619514'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2012/12/refactoring-to-patterns-in-delphi.html' title='Refactoring to patterns. Yet another TDD example coded in Delphi'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-7726759895638025532</id><published>2012-03-08T11:12:00.020-05:00</published><updated>2014-02-10T19:44:08.956-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="DUnit"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="Test Driven Development"/><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing"/><title type='text'>Test Driven Development in Delphi: The Basics</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
I intend to write a &lt;a href=&quot;http://en.wikipedia.org/wiki/Test-driven_development&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Test Driven Development (TDD)&lt;/a&gt; series, targeted for Delphi developers. I will use &lt;a href=&quot;http://dunit.sourceforge.net/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;DUnit&lt;/a&gt;, the &lt;b&gt;unit testing&lt;/b&gt; framework for Delphi.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Note folks that the purpose of this is NOT to discuss the Pros and Cons of &lt;b&gt;TDD&lt;/b&gt;, &lt;b&gt;Unit Testing&lt;/b&gt; or whatsoever. The purpose is just to give a few examples. I would love if you help me when the complexity starts climbing.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
If needed, for a quick understanding of what &lt;b&gt;TDD &lt;/b&gt;or &lt;b&gt;Unit Testing&lt;/b&gt; is, refer to the links above, or &lt;i&gt;check&lt;/i&gt; out the &lt;a href=&quot;http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html#TDD-Kent-Beck&quot; title=&quot;Test Driven Development: By Example (Kent Beck)&quot;&gt;book&lt;/a&gt; at the end of the article.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
In &lt;b&gt;TDD &lt;/b&gt;you don’t write the application code first, instead you write the test cases first. The &lt;b&gt;TDD&lt;/b&gt; cycle is as follows:&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;At the beginning you just write one test, and later on, more tests can be added.&lt;/li&gt;
&lt;li&gt;Make sure the initial test fails; this will validate the test harness.  &lt;/li&gt;
&lt;li&gt;Write some code to pass the test. Important: don’t over-code. Just add the code needed to pass the test and period. The code does not have to be elegant at this point.&lt;/li&gt;
&lt;li&gt;Run the test: if it fails, then you have to go back to step 3 and fix your code in order to pass the test. When you succeed, then move on to step 5.&lt;/li&gt;
&lt;li&gt;Improve and optimize your code: make it elegant, more efficient, avoid duplications, etc, etc. This is called code refactoring.&lt;/li&gt;
&lt;li&gt;When refactoring your code, maybe, by accident, you break the functionality. How can you be sure that everything is working as it should? Just re-run your test and it will tell you if the previous refactoring introduced a failure or not.&lt;/li&gt;
&lt;li&gt;Go to step 1 and add a new test if needed.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The example: let’s consider the chess game. The goal will be to implement the code to verify whether a piece is placed in a valid position within the board. We are only going to implement one test: &lt;i&gt;SetPositionTest&lt;/i&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I will number the columns (X coordinate) from 1 to 8 starting at the bottom left-hand corner. In the same way, I will number the rows (Y coordinate) from 1 to 8 starting at the bottom left-hand corner. &lt;/div&gt;
&lt;br /&gt;
8&lt;br /&gt;
7&lt;br /&gt;
6&lt;br /&gt;
5&lt;br /&gt;
4&lt;br /&gt;
3&lt;br /&gt;
2&lt;br /&gt;
1  2 3 4 5 6 7 8 &lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
For a step by step tutorial of how to use, configure and setup &lt;b&gt;DUnit &lt;/b&gt;you can read the &lt;a href=&quot;http://dunit.sourceforge.net/README.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;English&lt;/a&gt; or &lt;a href=&quot;http://dunit.sourceforge.net/README_CHT.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Chinese&lt;/a&gt; versions of the tutorial.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Initially, the testing code should look like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
unit ChessPiecesTests;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp;&amp;nbsp; TestFrameWork;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TPieceTest = class(TTestCase)&lt;br /&gt;
&amp;nbsp; published&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure SetPositionTest;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; ChessPieces;&lt;br /&gt;
&lt;br /&gt;
{ TPieceTest }&lt;br /&gt;
&lt;br /&gt;
procedure TPieceTest.SetPositionTest;&lt;br /&gt;
begin&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
initialization&lt;br /&gt;
&amp;nbsp; TestFramework.RegisterTest(TPieceTest.Suite);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
If you run that test, it will succeed since no &lt;i&gt;checks &lt;/i&gt;are being performed within the &lt;i&gt;SetPositionTest&lt;/i&gt; procedure. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Each test is composed by one or more &lt;i&gt;checks&lt;/i&gt;. I suggest adding the &lt;i&gt;checks &lt;/i&gt;little by little. Every time you add a &lt;i&gt;check&lt;/i&gt;, you should add business code to pass the corresponding test.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Now, let’s make the test fail on purpose. For that, let’s add one &lt;i&gt;check &lt;/i&gt;to the SetPositionTest procedure. &lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
procedure TPieceTest.SetPositionTest;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Check(True = False,  &#39;&#39;);&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;True &lt;/b&gt;is never &lt;b&gt;False&lt;/b&gt;. So, this test will fail. If it doesn’t fail, then something is wrong with you test harness. Fix it. You can remove this initial &lt;i&gt;check &lt;/i&gt;once you run the test and it fails.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Now, let’s add a real &lt;i&gt;check &lt;/i&gt;to our test. Something like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
procedure TPieceTest.SetPositionTest;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; Piece: TPiece;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Piece:= TPiece.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Test trivial (normal) workflow&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(4, 4) = True,  &#39;&#39;);&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Piece.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
If you run this test, you will get a compilation error! Yes, that’s right. You don’t have business code yet. You just have the test. This is what &lt;b&gt;TDD &lt;/b&gt;is all about: test first, business code later. Get the point?&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
To avoid the compilation error, we will code a separate unit (&lt;i&gt;ChessPieces&lt;/i&gt;) and we will add it to the &lt;i&gt;uses &lt;/i&gt;clause of our &lt;i&gt;ChessPiecesTests &lt;/i&gt;unit. &lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
unit ChessPieces;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TPiece = class&lt;br /&gt;
&amp;nbsp; private&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ TPiece }&lt;br /&gt;
&lt;br /&gt;
function TPiece.SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
begin&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Run the test again and now the compilation error is gone. Nonetheless, the test fails, because the &lt;i&gt;Piece.SetPosition(4, 4)&lt;/i&gt; evaluates to &lt;b&gt;False&lt;/b&gt;. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Let’s add the minimum business code possible to pass this test:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
function TPiece.SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= True;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
This passes the test. What? Yes, this passes the test, right? &lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
OK, what now? Well, we keep adding new &lt;i&gt;checks &lt;/i&gt;to the test and every time this happens, we need to add new business code in order to pass it. It is very important to add &lt;i&gt;checks &lt;/i&gt;to test the boundaries of whatever we are trying to code. I think you are getting the point, so I will just add a bunch of &lt;i&gt;checks &lt;/i&gt;at once:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
procedure TPieceTest.SetPositionTest;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; Piece: TPiece;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Piece:= TPiece.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Test trivial (normal) workflow&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(4, 4) = True,  &#39;&#39;);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Tests boundaries&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(1, 1) = True,  &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(1, 8) = True,  &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(8, 1) = True,  &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(8, 8) = True,  &#39;&#39;);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Test beyond the boundaries&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(3,    15) = False, &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(3,   -15) = False, &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(15,    3) = False, &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(15,   15) = False, &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(15,  -15) = False, &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(-15,   3) = False, &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(-15,  15) = False, &#39;&#39;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(-15, -15) = False, &#39;&#39;);&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Piece.Free;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The test above is even &lt;i&gt;checking &lt;/i&gt;for the attempts of positioning a piece outside the chess board.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
To pass that test let’s write some business code:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
function TPiece.SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= True;&lt;br /&gt;
&amp;nbsp; if (aY &amp;lt; 1) or (aY &amp;gt; 8) then Result:= False&lt;br /&gt;
&amp;nbsp; else if (aX &amp;lt; 1) or (aX &amp;gt; 8) then Result:= False;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Run the test and see how it passes. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The code above could be refactored or even rewritten. The tests will remain the same, allowing us to catch any bugs introduced with the code change.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
For instance, we could write the procedure above as follows:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
function TPiece.SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= (aX &amp;gt; 0) and&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aX &amp;lt; 9) and&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;gt; 0) and&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;lt; 9);&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Run the test, and it will tell you if this refactoring (or reimplementation) works ok. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
It’s important to note that a good test should cover all possible scenarios and workflows. Pay special attention to the boundaries. At this point, a good understanding of the requisites is indispensable. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Finally, more and more tests will be needed in a real world application. Each test will have its own &lt;i&gt;checks&lt;/i&gt;. Each test will cover one piece of the functionality: this is what &lt;b&gt;unit testing&lt;/b&gt; is intended for.&lt;br /&gt;
&lt;br /&gt;
I wrote a second article about &lt;a href=&quot;http://www.yanniel.info/2012/12/refactoring-to-patterns-in-delphi.html&quot; target=&quot;_blank&quot;&gt;TDD, code refactoring and design patterns in Delphi (click here)&lt;/a&gt;. I would appreciate any comments you could provide about it.&lt;br /&gt;
&lt;br /&gt;
For further reading I recommend you &lt;b&gt;Test Driven Development: By Example&lt;/b&gt; by &lt;i&gt;Kent Beck&lt;/i&gt;. Check it out just below:&lt;/div&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/post-edit.g?blogID=3701737190756431503&amp;amp;postID=7726759895638025532&quot; name=&quot;TDD-Kent-Beck&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0321146530/ref=as_li_tf_il?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321146530&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;Format=_SL160_&amp;amp;ASIN=0321146530&amp;amp;MarketPlace=US&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20&amp;amp;ServiceVersion=20070822&quot; /&gt;&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0321146530&quot; height=&quot;1&quot; style=&quot;border: none !important; margin: 0px !important;&quot; width=&quot;1&quot; /&gt;&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/7726759895638025532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7726759895638025532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7726759895638025532'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html' title='Test Driven Development in Delphi: The Basics'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-1098229902213601340</id><published>2012-02-03T14:26:00.014-05:00</published><updated>2012-12-13T20:13:38.449-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><title type='text'>Deep copying (cloning) objects in Delphi</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
When I first took a look at the prototype design pattern in &lt;a href=&quot;http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;GoF&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612&quot; style=&quot;border: none !important; margin: 0px !important; padding: 0px !important;&quot; width=&quot;1&quot; /&gt;(years ago), I realized that there was a big obstacle (challenge) to implement it in Delphi: How to write a routine to really clone (not just recreate) an object? In other words, how to perform a &lt;a href=&quot;http://en.wikipedia.org/wiki/Object_copy#Deep_copy&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;deep-copy&lt;/a&gt; of a living object in Delphi.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
There are approaches out there mimicking the &lt;b&gt;deep copy&lt;/b&gt; by simply calling the constructor and reassigning the state of the object by hand (I don’t like it). There are others exposing that a &lt;b&gt;deep copy&lt;/b&gt; could be accomplished for the descendants of &lt;i&gt;TPersistent &lt;/i&gt;by calling the &lt;i&gt;Assign &lt;/i&gt;method (I don’t like it either). &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
With the new RTTI extensions it seemed to me (and to others) that a &lt;b&gt;deep copy&lt;/b&gt; could be accomplished using &lt;a href=&quot;http://en.wikipedia.org/wiki/Reflection_%28computer_programming%29&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;reflection&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I was reluctant to write the routine myself since the work is not trivial. It could get really nasty because there might be composition, aggregation and God knows what within an arbitrary object. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
So I waited….&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Just a few days ago, I realized that I could use the JSON marshalling and unmarshalling features introduced in Delphi (2010?) to write the &lt;b&gt;deep copy&lt;/b&gt; method. So I came with this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
.....&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;uses&lt;br /&gt;
&amp;nbsp; DBXJSON, DBXJSONReflect;&lt;br /&gt;
.....&lt;br /&gt;
&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function DeepCopy(aValue: TObject): TObject;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; MarshalObj: TJSONMarshal;&lt;br /&gt;
&amp;nbsp; UnMarshalObj: TJSONUnMarshal;&lt;br /&gt;
&amp;nbsp; JSONValue: TJSONValue;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= nil;&lt;br /&gt;
&amp;nbsp; MarshalObj := TJSONMarshal.Create;&lt;br /&gt;
&amp;nbsp; UnMarshalObj := TJSONUnMarshal.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; JSONValue := MarshalObj.Marshal(aValue);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Assigned(JSONValue) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= UnMarshalObj.Unmarshal(JSONValue);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JSONValue.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MarshalObj.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; UnMarshalObj.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
You can now use it like this:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
.....&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;br /&gt;
&amp;nbsp; MyObject1,&lt;br /&gt;
&amp;nbsp; MyObject2: TMyObject;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //Regular object construction&lt;br /&gt;
&amp;nbsp; MyObject1:= TMyObject.Create;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Deep copying an object&lt;br /&gt;
&amp;nbsp; MyObject2:= TMyObject(DeepCopy(MyObject1));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Do something here&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject1.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject2.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I tested it with some complex cases and it seems to be working quite well. Anyhow, if you find any problems or limitations, please, let me know.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Now that you get the idea we can do more crazy things like patching &lt;i&gt;TObject &lt;/i&gt;(or any other class hierarchy) by using &lt;i&gt;helpers&lt;/i&gt;. Look at this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
.....&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp;&amp;nbsp; DBXJSON, DBXJSONReflect;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TObjectHelper = class helper for TObject&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function Clone: TObject;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
function TObjectHelper.Clone: TObject;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; MarshalObj: TJSONMarshal;&lt;br /&gt;
&amp;nbsp; UnMarshalObj: TJSONUnMarshal;&lt;br /&gt;
&amp;nbsp; JSONValue: TJSONValue;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= nil;&lt;br /&gt;
&amp;nbsp; MarshalObj := TJSONMarshal.Create;&lt;br /&gt;
&amp;nbsp; UnMarshalObj := TJSONUnMarshal.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; JSONValue := MarshalObj.Marshal(Self);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Assigned(JSONValue) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= UnMarshalObj.Unmarshal(JSONValue);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JSONValue.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MarshalObj.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; UnMarshalObj.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
All of a sudden, &lt;i&gt;TObject &lt;/i&gt;has a &lt;i&gt;Clone &lt;/i&gt;method! Call it like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
.....&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;br /&gt;
&amp;nbsp; MyObject1,&lt;br /&gt;
&amp;nbsp; MyObject2: TMyObject;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //Regular object construction&lt;br /&gt;
&amp;nbsp; MyObject1:= TMyObject.Create;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Cloning an object&lt;br /&gt;
&amp;nbsp; MyObject2:= TMyObject(MyObject1.Clone);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Do something here&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject1.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject2.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
If you think that &lt;i&gt;helpers &lt;/i&gt;are an aberration, you can still create a &lt;i&gt;TCloneable &lt;/i&gt;class with a &lt;i&gt;Clone&lt;/i&gt; method and inherit from it, right? You can even use the &lt;a href=&quot;http://www.yanniel.info/2011/09/decorator-design-pattern-in-delphi.html&quot;&gt;decorator pattern&lt;/a&gt; to attach a &lt;i&gt;Clone &lt;/i&gt;method to an object. You can do more…Share it with me, please. Thanks!&lt;/div&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/1098229902213601340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2012/02/deep-copy-clone-object-delphi.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/1098229902213601340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/1098229902213601340'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2012/02/deep-copy-clone-object-delphi.html' title='Deep copying (cloning) objects in Delphi'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-7202628466359617018</id><published>2012-01-26T15:01:00.016-05:00</published><updated>2012-12-13T20:14:12.033-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming"/><title type='text'>String comparison in Delphi</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Have you ever wondered how utilities like &lt;b&gt;Beyond Compare&lt;/b&gt; or &lt;b&gt;DIFF &lt;/b&gt;are comparing files? They do it (I guess) by solving the &lt;a href=&quot;http://en.wikipedia.org/wiki/Longest_common_subsequence&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;longest common subsequence (LCS) problem&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
After reading the Wikipedia article linked above, I obtained an overall view of the problem and I looked at the possible resolutions. So, I decided to implement a Delphi class to do the string comparison trick, which is the base for the text file comparison.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Let me put it as follows: given two strings to be compared, I want to highlight in &lt;span style=&quot;color: blue;&quot;&gt;blue &lt;/span&gt;the characters added to the first string and in &lt;span style=&quot;color: red;&quot;&gt;red &lt;/span&gt;the characters removed from it. The common (unchanged) characters will keep the default color.&lt;/div&gt;
&amp;nbsp; &lt;br /&gt;
&lt;u&gt;For example: &lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
String 1 = &lt;i&gt;Delphi allows both structural and object oriented programming.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
String 2 = &lt;i&gt;Does Delphi allow object oriented programming?&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Highlighted differences:&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;Does &lt;/span&gt;Delphi allow&lt;span style=&quot;color: red;&quot;&gt;s both structural and&lt;/span&gt; object oriented programming&lt;span style=&quot;color: red;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The Delphi class looks like this:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TDiff = record&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Character: Char;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CharStatus: Char;&amp;nbsp; //Possible values: [+, -, =]&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; TStringComparer = class&lt;br /&gt;
&amp;nbsp; ……………&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function Compare(aString1, aString2: string): TList&amp;lt;TDiff&amp;gt;;&lt;br /&gt;
&amp;nbsp; end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
When you call &lt;i&gt;TStringComparer.Compare&lt;/i&gt;, a generic list of &lt;i&gt;TDiff &lt;/i&gt;records is created. A &lt;i&gt;TDiff &lt;/i&gt;record contains a character and whether this character was added (&lt;i&gt;CharStatus &lt;/i&gt;= ‘+’), removed (&lt;i&gt;CharStatus &lt;/i&gt;= ‘-’) or unchanged (&lt;i&gt;CharStatus &lt;/i&gt;= ‘=’) in both strings under comparison.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Let’s drop two edits (&lt;i&gt;Edit1&lt;/i&gt;, &lt;i&gt;Edit2&lt;/i&gt;), a rich edit (&lt;i&gt;RichEdit1&lt;/i&gt;) and a button (&lt;i&gt;Button1&lt;/i&gt;) on a Delphi form. To highlight the differences put the following code in the &lt;i&gt;OnClick &lt;/i&gt;event of the button: &lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; Differences: TList&amp;lt;TDiff&amp;gt;;&lt;br /&gt;
&amp;nbsp; Diff: TDiff;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //Yes, I know...this method could be refactored ;-)&lt;br /&gt;
&amp;nbsp; Differences:= TStringComparer.Compare(Edit1.Text, Edit2.Text);&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.Clear;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelStart:= RichEdit1.GetTextLen;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for Diff in Differences do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Diff.CharStatus = &#39;+&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelAttributes.Color:= clBlue;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelText := Diff.Character;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if Diff.CharStatus = &#39;-&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelAttributes.Color:= clRed;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelText:= Diff.Character;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelAttributes.Color:= clDefault;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelText:= Diff.Character;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Differences.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
It looks like in the image below:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a alt=&quot;String comparison in Delphi: The LCS problem&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisPGE_cIzdNk_tRxSk3rQud3I3Dpe0sch2NC0byp4lUfG2Rx2BQnIaaAvCwB3uyYzl0QrkZzbtNNR2234vTz1WS0xW0Ih_E_DPr-qYZmZrp7G6YVcqBlfp_tqLoNTnSTtP7Z8vhC5tyBP2/s1600/String-comparison-in-Delphi-LCS-problem.jpg&quot; imageanchor=&quot;1&quot; rel=&quot;nofollow&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisPGE_cIzdNk_tRxSk3rQud3I3Dpe0sch2NC0byp4lUfG2Rx2BQnIaaAvCwB3uyYzl0QrkZzbtNNR2234vTz1WS0xW0Ih_E_DPr-qYZmZrp7G6YVcqBlfp_tqLoNTnSTtP7Z8vhC5tyBP2/s1600/String-comparison-in-Delphi-LCS-problem.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
For the full implementation read further down. Note that various optimizations could be added to the code below, but I didn’t implement them. Anyway, I hope this helps. Feedback is welcome! Feel free to find and correct bugs ;-)&lt;/div&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;code&gt;&lt;br /&gt;
unit StringComparison;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; Math, Generics.Collections;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TDiff = record&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Character: Char;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CharStatus: Char;&amp;nbsp; //Possible values: [+, -, =]&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; TStringComparer = class&lt;br /&gt;
&amp;nbsp; strict private&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; type TIntArray = array of array of Integer;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function LCSMatrix(X, Y: string): TIntArray;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class procedure ComputeDifferences(aLCSMatrix: TIntArray;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; X, Y: string;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i, j: Integer;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences: TList&amp;lt;TDiff&amp;gt;);&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function Compare(aString1, aString2: string): TList&amp;lt;TDiff&amp;gt;;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ TStringComparer }&lt;br /&gt;
&lt;br /&gt;
class function TStringComparer.LCSMatrix(X, Y: string): TIntArray;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; m, n,&lt;br /&gt;
&amp;nbsp; i, j: Integer;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; m:= Length(X);&lt;br /&gt;
&amp;nbsp; n:= Length(Y);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //We need one extra column and one extra row to be filled with zeroes&lt;br /&gt;
&amp;nbsp; SetLength(Result, m + 1, n + 1);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //First column filled with zeros&lt;br /&gt;
&amp;nbsp; for i := 0 to m do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[i, 0] := 0;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //First row filled with zeros&lt;br /&gt;
&amp;nbsp; for j:= 0 to n do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[0, j]:= 0;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Storing the lengths of the longest common subsequences&lt;br /&gt;
&amp;nbsp; //between prefixes of X and Y&lt;br /&gt;
&amp;nbsp; for i:= 1 to m do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for j:= 1 to n do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if X[i] = Y[j] then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[i, j] := Result[i-1, j-1] + 1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[i, j]:= Max(Result[i, j-1], Result[i-1, j]);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class procedure TStringComparer.ComputeDifferences(aLCSMatrix: TIntArray;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; X, Y: string;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i, j: Integer;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences: TList&amp;lt;TDiff&amp;gt;);&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; CharDiff: TDiff;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if (i &amp;gt; 0) and (j &amp;gt; 0) and (X[i] = Y[j]) then&lt;br /&gt;
&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ComputeDifferences(aLCSMatrix, X, Y, i-1, j-1, aDifferences);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.Character:= X[i];&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.CharStatus:= &#39;=&#39;;&amp;nbsp;&amp;nbsp; //The character did not change&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences.Add(CharDiff);&lt;br /&gt;
&amp;nbsp; end&lt;br /&gt;
&amp;nbsp; else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (j &amp;gt; 0) and ((i = 0) or (aLCSMatrix[i,j-1] &amp;gt;= aLCSMatrix[i-1,j])) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ComputeDifferences(aLCSMatrix, X, Y, i, j-1, aDifferences);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.Character:= Y[j];&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.CharStatus:= &#39;+&#39;; //The character was added&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences.Add(CharDiff);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (i &amp;gt; 0) and ((j = 0) or (aLCSMatrix[i,j-1] &amp;lt; aLCSMatrix[i-1,j])) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ComputeDifferences(aLCSMatrix, X, Y, i-1, j, aDifferences);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.Character:= X[i];&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.CharStatus:= &#39;-&#39;; //The character was removed&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences.Add(CharDiff);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
//This is a factory method&lt;br /&gt;
class function TStringComparer.Compare(aString1, aString2: string): TList&amp;lt;TDiff&amp;gt;;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; Matrix: TIntArray;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= TList&amp;lt;TDiff&amp;gt;.Create;&lt;br /&gt;
&amp;nbsp; Matrix:= LCSMatrix(aString1, aString2);&lt;br /&gt;
&amp;nbsp; ComputeDifferences(Matrix,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aString1, aString2,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Length(aString1), Length(aString2),&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/7202628466359617018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2012/01/lcs-string-comparison-in-delphi.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7202628466359617018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7202628466359617018'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2012/01/lcs-string-comparison-in-delphi.html' title='String comparison in Delphi'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisPGE_cIzdNk_tRxSk3rQud3I3Dpe0sch2NC0byp4lUfG2Rx2BQnIaaAvCwB3uyYzl0QrkZzbtNNR2234vTz1WS0xW0Ih_E_DPr-qYZmZrp7G6YVcqBlfp_tqLoNTnSTtP7Z8vhC5tyBP2/s72-c/String-comparison-in-Delphi-LCS-problem.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-4060170343467805884</id><published>2012-01-17T13:33:00.008-05:00</published><updated>2012-12-17T20:10:59.372-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="DUnit"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing"/><title type='text'>Testing the World Away: Recovery mission</title><content type='html'>&lt;div style=&quot;font-family: inherit; text-align: justify;&quot;&gt;
I was recently reviewing the &lt;a href=&quot;http://dunit.sourceforge.net/#Links&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;DUnit&lt;/a&gt; website and I noticed there is a broken link to an article titled “Testing The World Away”. It was written by Will Watts for QBS Software. November, 2000. &lt;br /&gt;
&lt;br /&gt;
I said “OK, maybe the article was relocated somewhere else in the QBS Software website”; so I tried a custom Google search &lt;a href=&quot;http://www.google.ca/search?as_q=&amp;amp;as_epq=Testing+the+World+Away&amp;amp;as_oq=&amp;amp;as_eq=&amp;amp;as_nlo=&amp;amp;as_nhi=&amp;amp;lr=&amp;amp;cr=&amp;amp;as_qdr=all&amp;amp;as_sitesearch=qbssoftware.com&amp;amp;as_occt=any&amp;amp;safe=images&amp;amp;tbs=&amp;amp;as_filetype=&amp;amp;as_rights=&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&quot;Testing the World Away&quot; site:qbssoftware.com&lt;/a&gt;. As you can see the article was either banned from Google or removed completely from the QBS Software website.&lt;br /&gt;
&lt;br /&gt;
Once again I said “OK, maybe there’s a copy of the article somewhere else on the Internet” and I tried a second custom Google search &lt;a href=&quot;http://www.google.ca/search?as_q=&amp;amp;as_epq=Testing+the+World+Away&amp;amp;as_oq=&amp;amp;as_eq=&amp;amp;as_nlo=&amp;amp;as_nhi=&amp;amp;lr=&amp;amp;cr=&amp;amp;as_qdr=all&amp;amp;as_occt=any&amp;amp;safe=images&amp;amp;tbs=&amp;amp;as_filetype=&amp;amp;as_rights=&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&quot;Testing the World Away&quot;&lt;/a&gt;. At this point I convinced myself that the article was gone for good.&lt;br /&gt;
&lt;br /&gt;
I am a curious guy, so I tried one final thing: I looked up the broken link[1] in the &lt;a href=&quot;http://www.archive.org/about/about.php&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Internet Archive&lt;/a&gt; website and wallah!, they came with an archived version of the article.&lt;br /&gt;
&lt;br /&gt;
I have shared below a copy of the article so that we can take a look. As I said, this article is not mine, and if the author(owner) at some point request me to deleted it from my blog, I will do so.&lt;br /&gt;
&lt;br /&gt;
[1] &lt;a href=&quot;http://www.qbss.com/html/news/news_body.asp?content=ARTICLE&amp;amp;link=368&amp;amp;zone=&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://www.qbss.com/html/news/news_body.asp?content=ARTICLE&amp;amp;link=368&amp;amp;zone=&lt;/a&gt;&amp;nbsp; &lt;/div&gt;
&lt;div style=&quot;font-family: inherit; text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: inherit; text-align: justify;&quot;&gt;
&lt;span style=&quot;color: blue; font-size: small;&quot;&gt;&lt;span class=&quot;COLOURED&quot;&gt;&lt;b&gt;Testing the World Away&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: green; font-size: small;&quot;&gt;&lt;b&gt;(01 November 2000)&lt;/b&gt;&lt;/span&gt;    &lt;/div&gt;
&lt;div style=&quot;font-family: inherit; text-align: justify;&quot;&gt;
&lt;span style=&quot;color: black; font-size: small;&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2 style=&quot;font-family: inherit; text-align: justify;&quot;&gt;
&lt;span style=&quot;color: black; font-size: small;&quot;&gt;Testing the World Away&lt;/span&gt;&lt;/h2&gt;
&lt;div style=&quot;font-family: inherit; text-align: justify;&quot;&gt;
&lt;span style=&quot;color: black; font-size: small;&quot;&gt; The software methodology of the hour is Kent Beck’s ‘Extreme Programming’. Mr  Beck is a Smalltalk programmer by trade and, I think, a bit of a lad by  inclination (evidence: the bibliography of his book Extreme Programming  Explained, as well as citing standards such as The Mythical Man-Month and Design  Patterns, also recommends Cynthia Heimel’s Sex Tips for Girls. Right on!). I  find some of his ideas unconvincing. Pair Programming for example, where one  programmer sits at the keyboard and works while the other does something else -  possibly flower-arranging, my concentration lapsed at this point in the text as  I tried to imagine any manager I’ve met who would permit this exciting way of  increasing his costs - seems too beautiful and delicate for our mortal coil. On  the other hand his approach to testing, and the free libraries based on his  design that are around to back it up, comes much nearer to hitting, as I suppose  Ms Heimel might put it, my programming G-spot.&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;span style=&quot;color: black; font-size: small;&quot;&gt; Mr Beck’s idea is that as you write each bit of code, you should also write a  little test to go with it. As the project develops, the library of tests builds  up in parallel. After each alteration or addition, you rerun the test suite to  discover if you have broken anything. One of the rules - and I think it is an  important one - is that the test suite must be able to run all the way through,  pass or fail, without operator intervention. So although it is a chore to write  the tests, the effort put in is ‘banked’, and it costs very little to rerun them  - with the consequence that they do get rerun.&lt;br /&gt;
&lt;br /&gt;
Mr Beck has had brushes with those GUI automated tools that record keystrokes  and mouse-clicks into some sort of script and then let you play your actions  back at the application to be tested and verify its responses. These look like  they are going to do the job from the description on the packet but in practice,  as Mr Beck correctly observes, they are not very robust. Remove one edit box, or  merely nudge it three pixels to the right, or change the screen resolution -  suddenly the whole thing falls flat on its face. Testing code, he decided,  should be written at the same level and in the same language as the stuff to be  tested.&lt;br /&gt;
&lt;br /&gt;
Tests also need structure. One needs to see results presented in a consistent  way, to be able to select specific tests to run and so on. To this end, Mr Beck  wrote a library of Smalltalk classes - a framework - called ‘SmalltalkUnit’ or  ‘SUnit’. Later on he collaborated with no less than Erich Gamma to produce a  Java version called ‘JUnit’. The idea ‘took on’, and now there are versions for  an impressive range of languages including C++, Eiffel, Objective-C, Perl,  Python, Visual Basic and even Visual Objects. You&#39;ll find them all listed at  &lt;a href=&quot;http://www.xprogramming.com/software.htm&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://www.xprogramming.com/software.htm&lt;/a&gt;.  If you are familiar with my language prejudices, you will be unsurprised to  learn that I am going to discuss a Delphi language version called DUnit.  Originally ported from the Java version by Juancarlo Añez, this library is now  maintained on an Open Source basis by the DUnit group at SourceForge:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://sourceforge.net/projects/dunit/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://sourceforge.net/projects/dunit/&lt;/a&gt;.  This library makes heavy use of function overloading, so you’ll need Delphi 4 or  later to play with it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Who DUnit?&lt;/b&gt;&lt;br /&gt;
Figure 1 shows a suite of DUnit tests that  have been run using the library’s GUI interface. The top pane lists all the  tests available. These are organised in a hierarchy: a suites of tests may  contain either individual test cases or other suites - a Composite pattern. In  the part of the hierarchy visible, I have set up a suite called ‘SFW COM Library  tests’ that, in turn, contains suites subdivided by the class being tested. The  TTestDoubleChannel suite operates on a class called TDoubleChannel, and below  TTestDoubleChannel are tests on individual methods. There are checkboxes to  switch individual tests and parts of the hierarchy on and off; these interact  with some useful buttons at the bottom of the dialog to allow speedy selection  of all or part of the suite.&lt;br /&gt;
&lt;br /&gt;
Each test is colour-coded by the result of the last run. Green, obviously,  indicates success; magenta a ‘failure’, that is that an unexpected result was  obtained; red, an ‘error’, that the test threw an exception. The lower pane  lists all the failures and errors together with descriptive messages. In between  the two panes are progress bars indicating progress through the test suite and  success rate.&lt;br /&gt;
&lt;br /&gt;
Figure 2 shows DUnit’s text mode version after running the same test suite as  Figure 1, and I hope that you can see it has produced the same results. Although  lacking the eye candy and versatility of the GUI test runner, this console  version requires no interaction and sets its exit code non-zero on failure. This  makes it ideal for placing in a make file, or incorporating into an automated  testing procedure. By the way, to make my test suite code run as a console  application, I substituted one .DPR file for another - about 10 seconds’  work.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How it works&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The key class in DUnit’s framework is &lt;i&gt;TTestCase&lt;/i&gt;. All the actual  testing code is placed in classes that you derive from it. It’s easiest to see  how this works with a snippet of code. Figure 3 shows a trivial example of a  program that tests 1 + 1 = 2.&lt;br /&gt;
&lt;br /&gt;
First look at the Project1TestCases.pas unit. TTestCaseFirst is derived from  TTestCase, adding one published method testFirst. Three features of this method  are important: that it is a parameterless procedure, that it has public scope,  and that its name begins ‘test…’. These features enable DUnit to discover and  run the method without the need to call it explicitly in hand-generated code. It  is sufficient to declare a method of a TTestCase-derived class that follows  these rules to get it run.&lt;br /&gt;
&lt;br /&gt;
The implementation of testFirst is a single line: I ‘assert’ that 1 + 1 = 2.  (Old Delphi hands and practitioners of design-by-contract may be raising their  eyebrows at this strange use of Assert. Please bear with me, explanations and  excuses will follow in due course.)&lt;br /&gt;
&lt;br /&gt;
At the bottom of Project1TestCases.pas, in an initialization section, is the  call registerTest(&#39;&#39;, TTestCaseFirst); which registers TTestCaseFirst with the  framework. The first parameter is the ‘path’, it controls where a test case  appears in the hierarchy. By supplying an empty string I am placing it below the  root node.&lt;br /&gt;
&lt;br /&gt;
The project file Project1Test.dpr references DUnit library units  TestFrameWork and &lt;i&gt;GUITestRunner&lt;/i&gt; as well as Project1TestCases.pas. A  single line replaces the standard Delphi GUI project code:  &lt;i&gt;GUITestRunner.runTest(TestFramework.registeredTests);&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
This creates and displays the GUI interface shown in Figure 1. And that’s it.  To add further arithmetic tests, just write extra test… methods, for example&lt;br /&gt;
&lt;br /&gt;
procedure TTestCaseFirst.testSecond;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Assert(2 + 2 = 5,  &#39;Oops!&#39;);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
This mistake will be flagged as a magenta-coloured failure when it is run.&lt;br /&gt;
&lt;br /&gt;
In reality one uses DUnit on classes rather than trivial arithmetic.  Instances of classes can be placed as member data in the TTestCase-derived  class, and two virtual methods, SetUp and TearDown, can be overridden to create  and destroy them around each test method. Figure 4 sketches how this is done.  Note that SetUp is called before, and TearDown after, each test method. This  isolation of the test methods from each other is deliberate - you shouldn’t  build a sequence of tests where one method is dependant on those called  before.&lt;br /&gt;
I mentioned DUnit’s ability to build up suites from multiple test cases. This  is accomplished using the TTestSuite class:&lt;br /&gt;
&lt;i&gt;Suite := TTestSuite.create(&#39;A  suite&#39;);&lt;br /&gt;
Suite.addTests(TTestCaseFirst);&lt;br /&gt;
Suite.addTests(TTestCaseMyClass);&lt;/i&gt;&lt;br /&gt;
The populated suite can then be passed to registerTest as before.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;All About Assert&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It’s time to own up to a problem with DUnit. The library’s use of the Assert  function to check the test conditions is rather perverse. Assert already has a  well-understood role in Delphi code, and this isn’t it. How did it get there?  Well, you will recall that DUnit is a port of a Java library called JUnit and  the Java language, I am informed, doesn’t have an Assert in the C++/Delphi  sense. Unfortunately the ‘Assert’ name was carried across with the rest of  JUnit. An easy mistake to make:&amp;nbsp; it has also happened to the people doing a  C++ version of JUnit.&lt;br /&gt;
&lt;br /&gt;
However, there is a move afoot among the DUnit developers to change the  function&#39;s name, probably to Check, and also to add a family of useful  overloaded methods with names like CheckEqual, CheckNotEqual and so on. With  luck this will have gone through by the time you read this.&lt;br /&gt;
&lt;br /&gt;
DUnit is very much work-in-progress, and there are a number of interesting  additions and enhancements coming into view. Two add-ons have just been released  - one standalone, one integrated with the IDE enhancer CodeRush - which will  generate skeleton test case code from the declaration of a class that is to be  tested. As well as extra facilities for test repetition and set-up that I have  not covered here, there are also plans to add special support for databases,  multi-threading and GUI testing.&lt;br /&gt;
&lt;br /&gt;
No technique can stop testing from being a fag. But I have found that the  accumulation of a permanent test suite, and the improved confidence in my code  developed in this way make DUnit’s use worthwhile. Go on: pull it down and have  a go!&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Will Watts is a programmer and occasional journo who lives in Chiswick.  To his pleasure, his Snobol column in Developers Review has not, as far as he  knows, been nominated for the Worst IT Journalism 2000 Award.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Books:&lt;/b&gt;&lt;br /&gt;
Extreme Programming Explained by Kent Beck, pub  Addison-Wesley, ISBN 0-201-61641-6. Mr Beck’s philosophy of software  development.&lt;br /&gt;
Refactoring - Improving the Design of Existing Code by Martin  Fowler et al, pub Addison-Wesley, ISBN 0-201-48567-2. Includes good description  of JUnit.&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/4060170343467805884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2012/01/testing-world-away.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4060170343467805884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4060170343467805884'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2012/01/testing-world-away.html' title='Testing the World Away: Recovery mission'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-8418763582187933434</id><published>2012-01-09T18:04:00.011-05:00</published><updated>2012-12-13T20:15:21.535-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="API"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="XML"/><title type='text'>Delphi Implementation for the OpenSubtitles API</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;a href=&quot;http://www.opensubtitles.org/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;OpenSubtitles.org&lt;/a&gt; allows searching and hosting subtitles in several formats (SRT, SUB, etc.) and pretty much every language. It currently has a vast database of subtitles (expanding every day). OpenSubtitles.org also exposes a XML-RPC based API that can be used in order to build third party applications with subtitle features.&lt;br /&gt;
&lt;br /&gt;
I am writing a Delphi app to search subtitles in the OpenSubtitles.org database... I thought it would be nice to have a Delphi wrapper for the whole API. Below is my three cents contribution. I will probably implement and share more methods in the future, but feel free to contribute as well.&amp;nbsp; Take a look at the &lt;a href=&quot;http://trac.opensubtitles.org/projects/opensubtitles/wiki/XMLRPC&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;full API methods list&lt;/a&gt;.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
XML-RPC stands for XML Remote Procedure Call. It allows “remote procedure calling using HTTP as the transport and XML as the encoding”. [&lt;a href=&quot;http://xmlrpc.scripting.com/spec&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://xmlrpc.scripting.com/spec&lt;/a&gt;]. XML-RPC is really easy to implement: in the code below I have used formatted strings to conform the XML requests (XML encoding pending) and the Indy TIdHTTP component to send the requests. &lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
unit OpensubtitlesAPI;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; IdHTTP, Classes, SysUtils;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; function LogIn(aUsername, aPassword,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aLanguage, aUserAgent: string): string;&lt;br /&gt;
&amp;nbsp; function LogOut(aToken: string): string;&lt;br /&gt;
&amp;nbsp; function SearchSubtitles(aToken, aSublanguageID,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aMovieHash: string;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aMovieByteSize: Cardinal): string;&amp;nbsp; overload;&lt;br /&gt;
&amp;nbsp; function SearchSubtitles(aToken, aSublanguageID: string;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aImdbID: Cardinal): string; overload;&lt;br /&gt;
&amp;nbsp; function SearchSubtitles(aToken, aSublanguageID,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aQuery: string): string;&amp;nbsp; overload;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
function XML_RPC(aRPCRequest: string): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; cURL= &#39;http://api.opensubtitles.org/xml-rpc&#39;;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; lHTTP: TIdHTTP;&lt;br /&gt;
&amp;nbsp; Source,&lt;br /&gt;
&amp;nbsp; ResponseContent: TStringStream;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; lHTTP := TIdHTTP.Create(nil);&lt;br /&gt;
&amp;nbsp; lHTTP.Request.ContentType := &#39;text/xml&#39;;&lt;br /&gt;
&amp;nbsp; lHTTP.Request.Accept := &#39;*/*&#39;;&lt;br /&gt;
&amp;nbsp; lHTTP.Request.Connection := &#39;Keep-Alive&#39;;&lt;br /&gt;
&amp;nbsp; lHTTP.Request.Method := &#39;POST&#39;;&lt;br /&gt;
&amp;nbsp; lHTTP.Request.UserAgent := &#39;OS Test User Agent&#39;;&lt;br /&gt;
&amp;nbsp; Source := TStringStream.Create(aRPCRequest);&lt;br /&gt;
&amp;nbsp; ResponseContent:= TStringStream.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lHTTP.Post(cURL, Source, ResponseContent);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= ResponseContent.DataString;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= &#39;&#39;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; lHTTP.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Source.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ResponseContent.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function LogIn(aUsername, aPassword, aLanguage, aUserAgent: string): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; LOG_IN = &#39;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;methodCall&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;methodName&amp;gt;LogIn&amp;lt;/methodName&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;params&amp;gt;&#39;&amp;nbsp;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param&amp;gt;&#39;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param&amp;gt;&#39;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%1:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param&amp;gt;&#39;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%2:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param&amp;gt;&#39;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%3:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;/params&amp;gt;&#39;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;/methodCall&amp;gt;&#39;;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(LOG_IN, [aUsername, aPassword, aLanguage, aUserAgent]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function LogOut(aToken: string): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; LOG_OUT = &#39;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;methodCall&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;methodName&amp;gt;LogOut&amp;lt;/methodName&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;params&amp;gt;&#39;&amp;nbsp;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param&amp;gt;&#39;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;/params&amp;gt;&#39;&amp;nbsp; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;/methodCall&amp;gt;&#39;;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(LOG_OUT, [aToken]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SearchSubtitles(aToken, aSublanguageID, aMovieHash: string; aMovieByteSize: Cardinal): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; SEARCH_SUBTITLES = &#39;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;methodCall&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;methodName&amp;gt;SearchSubtitles&amp;lt;/methodName&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;params&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;array&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;data&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;struct&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;name&amp;gt;sublanguageid&amp;lt;/name&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%1:s&amp;lt;/string&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;name&amp;gt;moviehash&amp;lt;/name&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%2:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;name&amp;gt;moviebytesize&amp;lt;/name&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;double&amp;gt;%3:d&amp;lt;/double&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/struct&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/data&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/array&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39; &amp;lt;/params&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;/methodCall&amp;gt;&#39;;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(SEARCH_SUBTITLES, [aToken, aSublanguageID, aMovieHash, aMovieByteSize]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SearchSubtitles(aToken, aSublanguageID: string;&lt;br /&gt;
&amp;nbsp; aImdbID: Cardinal): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; SEARCH_SUBTITLES = &#39;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;methodCall&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;methodName&amp;gt;SearchSubtitles&amp;lt;/methodName&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;params&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;array&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;data&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;struct&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;name&amp;gt;sublanguageid&amp;lt;/name&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%1:s&amp;lt;/string&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;name&amp;gt;imdbid&amp;lt;/name&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%2:d&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/struct&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/data&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/array&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39; &amp;lt;/params&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;/methodCall&amp;gt;&#39;;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(SEARCH_SUBTITLES, [aToken, aSublanguageID, aImdbID]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SearchSubtitles(aToken, aSublanguageID,&lt;br /&gt;
&amp;nbsp; aQuery: string): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; SEARCH_SUBTITLES = &#39;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;methodCall&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;methodName&amp;gt;SearchSubtitles&amp;lt;/methodName&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;params&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;array&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;data&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;struct&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;name&amp;gt;sublanguageid&amp;lt;/name&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%1:s&amp;lt;/string&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;name&amp;gt;query&amp;lt;/name&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%2:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/member&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/struct&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/data&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/array&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp; &amp;lt;/value&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;nbsp; &amp;lt;/param&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39; &amp;lt;/params&amp;gt;&#39; +&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;&amp;lt;/methodCall&amp;gt;&#39;;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(SEARCH_SUBTITLES, [aToken, aSublanguageID, aQuery]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end. &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Finally, I present you some sample calls:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Logging- in anonymously (empty credentials) and getting the token: &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;LogIn(&#39;&#39;, &#39;&#39;, &#39;en&#39;, &#39;OS Test User Agent&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Logging- out (disposing the token): &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;LogOut(&lt;/code&gt;&lt;code&gt;&#39;&lt;/code&gt;&lt;code&gt;81nt6bgl9vde06l3ptq7v1a7r1&lt;/code&gt;&lt;code&gt;&#39;&lt;/code&gt;&lt;code&gt;);&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Search English subtitles for the movie whose ImdbID is &lt;i&gt;120737&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;SearchSubtitles(Edit1.Text, &#39;eng&#39;, 120737);&lt;/code&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Search English subtitles for &lt;i&gt;The Lord of the Rings&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;SearchSubtitles(Edit1.Text, &#39;eng&#39;, &#39;The Lord of the Rings&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Search English subtitles for the movie whose hash is &lt;i&gt;7d9cd5def91c9432 &lt;/i&gt;and size is &lt;i&gt;735934464&lt;/i&gt;.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;SearchSubtitles(Edit1.Text, &#39;eng&#39;, &#39;7d9cd5def91c9432&#39;, 735934464);&lt;/code&gt;&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/8418763582187933434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2012/01/open-subtitles-api-in-delphi.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8418763582187933434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8418763582187933434'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2012/01/open-subtitles-api-in-delphi.html' title='Delphi Implementation for the OpenSubtitles API'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-916727228547268188</id><published>2011-12-14T13:18:00.019-05:00</published><updated>2012-12-13T20:15:46.219-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Google"/><category scheme="http://www.blogger.com/atom/ns#" term="PageRank"/><title type='text'>Request the Google PageRank the Delphi way</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
In this post I am implementing the Delphi way to request the&lt;a href=&quot;http://en.wikipedia.org/wiki/PageRank#Google_Toolbar&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt; Google Toolbar’s PageRank&lt;/a&gt; (PR). As an example, if I want to look up the PR of my blog (http://www.yanniel.info/), I will have to query the following URL: &lt;/div&gt;
&lt;br /&gt;
&lt;a href=&quot;http://toolbarqueries.google.com/tbr?client=navclient-auto&amp;amp;features=Rank&amp;amp;ch=64012521073&amp;amp;q=info:http://www.yanniel.info/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://toolbarqueries.google.com/tbr?client=navclient-auto&amp;amp;features=Rank&amp;amp;ch=64012521073&amp;amp;q=info:http://www.yanniel.info/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So, if you try&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
Writeln(Curl(&#39;http://toolbarqueries.google.com/tbr?client=navclient-auto&amp;amp;features=Rank&amp;amp;ch=64012521073&amp;amp;q=info:http://www.yanniel.info/&#39;));&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
You will get the following output:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rank_1:1:0&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Oops, at this moment my PageRank is pathetic (PR = 0). Hopefully it will get better someday ;-)&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
You can find the implementation of the &lt;i&gt;Curl &lt;/i&gt;function in my previous post: &lt;a href=&quot;http://www.yanniel.info/2011/02/fetch-web-page-delphi-curl-indy.html&quot; target=&quot;_blank&quot;&gt;Fetching a web page with Delphi&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Now that you get the idea, it’s time to generalize our implementation in order to get the PR of any web page.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
In the URL above there are two dynamic parameters that we need to understand:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Parameter &lt;b&gt;q:&lt;/b&gt; This is the concatenation of “info:” plus the encoded URL for which we want to get the PR. It is mandatory to lead the encoded URL with “http://”. Don’t forget to put a “/” after the top domain, ei, “.info/”, not “.info”. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Parameter &lt;b&gt;ch&lt;/b&gt;: Obtaining this parameter is the tricky part. We have to hash the concatenation of “info:” plus our target URL (ei. http://www.yanniel.info/) using the &lt;a href=&quot;http://burtleburtle.net/bob/hash/perfect.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;minimal perfect hashing&lt;/a&gt; algorithm invented by Bob Jenkins. The outcome will be a number, which corresponds to the value of our &lt;b&gt;ch&lt;/b&gt; parameter. We are hashing something like “info:http://www.yanniel.info/”.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I didn’t have the time (or the desire) to understand and implement the minimal perfect hashing algorithm from scratch. So, I ported this &lt;a href=&quot;http://www.codeproject.com/KB/aspnet/Google_Pagerank.aspx&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;C# implementation&lt;/a&gt; into Delphi code. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
There’s one detail worth mentioning about the implementation. In the original C# code there’s a switch statement that falls all the way through the different cases. I needed to combine a &lt;i&gt;case&lt;/i&gt; statement and some &lt;i&gt;goto &lt;/i&gt;statements in order to accomplish the same in Delphi. &lt;strike&gt;Really, I tried to avoid the &lt;i&gt;goto&lt;/i&gt;, I always do, but I couldn’t find a better and cleaner way of implementation. I was telling myself how bad programmer I was, and then, I read one entry in &lt;a href=&quot;http://www.delphifeeds.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Delphi Feeds&lt;/a&gt; talking about the minimal perfect hashing algorithm, and more than that, highlighting the &lt;i&gt;goto &lt;/i&gt;issue. Nick Hodges wrote the &lt;a href=&quot;http://www.nickhodges.com/post/Flotsam-and-Jetsam-51.aspx&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;post&lt;/a&gt;: thank you Nick... now I can sleep again.&lt;/strike&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;strike&gt;It seems that I am not the only one considering this &lt;i&gt;goto &lt;/i&gt;usage as an exception to the good practice of “don’t use goto statements”. The funny thing is that I read Nick’s post without the intention of finding anything about the minimal perfect hashing algorithm or about the &lt;i&gt;goto &lt;/i&gt;stuff. It’s really a big coincidence that we were considering to write about the minimal perfect hashing algorithm (and the &lt;i&gt;goto &lt;/i&gt;gotcha) at the same time. &lt;/strike&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: blue;&quot;&gt;I wrote the strikeout text above initially; but Brian (first comment below) found a clean way to avoid the &lt;i&gt;goto &lt;/i&gt;in this situation. I really thank Brian for his contribution, and next time, I won&#39;t quit that easily in removing the &lt;i&gt;goto &lt;/i&gt;;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;-&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: blue;&quot;&gt;)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I am putting everything together in the Delphi console application below. I bet you can reuse the &lt;i&gt;BobJenkinsHash &lt;/i&gt;function in the &lt;i&gt;Generics.Default.pas&lt;/i&gt; unit to make the PR implementation more compact. I didn’t know about the &lt;i&gt;BobJenkinsHash &lt;/i&gt;function shipped with Delphi before reading Nick’s post; which is why I am keeping my original implementation.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Finally, this is how you request the Google PageRank in Delphi:&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;program Project1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;{$APPTYPE CONSOLE}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;{$R *.res}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; System.SysUtils, IdHTTP, IdURI, Classes;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;type&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; TByteArray =&amp;nbsp; array of Byte;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function Curl(aURL: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;const&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; cUSER_AGENT = &#39;Mozilla/4.0 (MSIE 6.0; Windows NT 5.1)&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; IdHTTP: TIdHTTP;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Stream: TStringStream;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result := &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; IdHTTP := TIdHTTP.Create(nil);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Stream := TStringStream.Create;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdHTTP.Request.UserAgent := cUSER_AGENT;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdHTTP.Get(aURL, Stream);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := Stream.DataString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stream.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdHTTP.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure Hashing(var a, b, c: Integer);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a xor (c shr 13);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b xor (a shl 8);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c xor (b shr 13);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a xor (c shr 12);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:=&amp;nbsp; b xor (a shl 16);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c xor (b shr 5);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a xor (c shr 3);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b xor (a shl 10);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c xor (b shr 15);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function StrOrd(aValue: string): TByteArray;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; I: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; SetLength(Result, Length(aValue));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; for I:= 1 to Length(aValue) do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[I-1]:= Ord(aValue[I]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function PerfectHash(aURL: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; url: TByteArray;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; _length,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; k, len: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a, b, c: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;label&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; One,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Two,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Three,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Four,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Five,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Six,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Seven,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Eight,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Nine,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Ten;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; url:= StrOrd(aURL);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; _length:= Length(url);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; k:= 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; len:= _length;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= $9E3779B9;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= $9E3779B9;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= $E6359A60;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; while (len &amp;gt;= 12) do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 0] + (url[k + 1] shl 8) +&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (url[k + 2] shl 16) + (url[k + 3] shl 24) );&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 4] + (url[k + 5] shl 8) +&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (url[k + 6] shl 16) + (url[k + 7] shl 24) );&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:= c+ (url[k + 8] + (url[k + 9] shl 8) +&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (url[k + 10] shl 16) + (url[k + 11] shl 24));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Hashing(a, b, c);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; k:= k + 12;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; len:= len - 12;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c + integer(_length);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; case len of&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 11: begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:= c + (url[k + 10] shl 24);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Ten;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10: begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ten:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:= c + (url[k + 9] shl 16);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Nine;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Nine:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:= c + (url[k + 8] shl 8);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Eight;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Eight:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 7] shl 24);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Seven;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Seven:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 6] shl 16);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Six;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Six:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 5] shl 8);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Five;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Five:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 4]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Four;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Four:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 3] shl 24);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Three;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Three:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 2] shl 16);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Two;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Two:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 1] shl 8);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto One;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; One:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 0]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Hashing(a, b, c);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= Format(&#39;6%0:u&#39;, [c]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function GetPageRank(aURL: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;const&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; cToolbarQueriesURL = &#39;http://toolbarqueries.google.com/tbr?client=navclient-auto&amp;amp;features=Rank&amp;amp;ch=%0:s&amp;amp;q=%1:s&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; CH, Q: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; aURL:= StringReplace(aURL, &#39;http://&#39;, &#39;&#39;, []);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; if Pos(&#39;/&#39;, aURL) = 0 then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aURL:= aURL + &#39;/&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; aURL:= &#39;http://&#39; + aURL;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; CH:= PerfectHash(&#39;info:&#39; + aURL);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Q:= &#39;info:&#39; + TIdURI.URLEncode(aURL);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= Curl(Format(cToolbarQueriesURL, [CH, Q]));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Writeln(GetPageRank(&#39;http://www.yanniel.info/&#39;));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Writeln(GetPageRank(&#39;http://www.delphifeeds.com/&#39;));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Writeln(GetPageRank(&#39;http://www.google.com/&#39;));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/916727228547268188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/12/google-pagerank-in-delphi.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/916727228547268188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/916727228547268188'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/12/google-pagerank-in-delphi.html' title='Request the Google PageRank the Delphi way'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-4798569634632094914</id><published>2011-12-09T11:08:00.013-05:00</published><updated>2012-12-13T20:16:00.712-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Script"/><title type='text'>Pascal Server Pages – Pascal Script</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Without getting too technical, I would define a Pascal Server Page (PSP) as a dynamic web page containing embedded Pascal Script (PS) code.&amp;nbsp; When a web request is made, the PS code needs to be executed (interpreted) in the server side and outputted into the proper format (HTML, XML, JSON, text, etc). A PSP is commonly stored as a text file in the Web Server and it could be a mixture of PS code plus any other static content. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
This is an example of PSP:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;head&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;This is a Pascal Server Page&amp;lt;/title&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;/head&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;body&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;% begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(&#39;Hello World&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;I am going to use Pascal Script to write a few numbers...&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;% var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for i:=1 to 10 do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(i);&amp;nbsp; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&amp;gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The code above is an HTML armature containing some PS code. The PS code has been isolated within the “&amp;lt;%” and “%&amp;gt;” tokens. The PS code is executed in the server and the output (if any) is embedded into the HTML template.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
So, if a browser asks for the page above, it will actually get plain HTML code as the one below:&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;head&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;This is a Pascal Server Page&amp;lt;/title&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;/head&amp;gt;&amp;nbsp; &lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;body&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Hello World&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;I am going to use Pascal Script to write a few numbers...&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;lt;br&amp;gt;2&amp;lt;br&amp;gt;3&amp;lt;br&amp;gt;4&amp;lt;br&amp;gt;5&amp;lt;br&amp;gt;6&amp;lt;br&amp;gt;7&amp;lt;br&amp;gt;8&amp;lt;br&amp;gt;9&amp;lt;br&amp;gt;10&amp;lt;br&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
This is all good. The only problem is that the PS code is not going to be magically executed. We need a server side component to do the PS interpretation.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I have seen a couple of intents to build such server side component in the Internet. Anyhow, I bring you my own proposal: create a Web Broker application with Pascal Scripting capabilities. To provide the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/XE2/en/Using_Web_Broker_Index&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Web Broker&lt;/a&gt; application with the scripting capabilities, I will use &lt;a href=&quot;http://www.remobjects.com/ps.aspx&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Pascal Script from RemObjects&lt;/a&gt;. You need to &lt;a href=&quot;http://www.remobjects.com/trials.aspx#free&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;download&lt;/a&gt; and install Pascal Script if you want to try my code.&amp;nbsp; &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
The workflow goes as follows:&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;The Web Broker application receives a Web Request.&lt;/li&gt;
&lt;li&gt;The Web Broker application finds the corresponding Pascal Server Page and loads its content to a buffer variable.&lt;/li&gt;
&lt;li&gt;The content of the buffer variable is parsed in order to find the PS tokens (I will use &lt;a href=&quot;http://docwiki.embarcadero.com/VCL/en/RegularExpressions.TRegEx&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;RegEx&lt;/a&gt; to do the parsing). &lt;/li&gt;
&lt;li&gt;Each PS block is compiled to Bytecode and then executed in the server. (I will use the Pascal Script library from RemObjects for this purpose).&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The output generated from the execution of each PS block replaces its corresponding “&amp;lt;%......%&amp;gt;” block.&lt;/li&gt;
&lt;li&gt;The Web Broker app serves the response.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I developed a VCL standalone Web Broker application as a proof of concept (it could be an ISAPI dll as well). See it in action in the following video:&lt;/div&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/NMBn6BjNEW0&quot; width=&quot;420&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
That application is just a prototype. I really believe that we could build a robust server side component to leverage enterprise Pascal Server Pages. I used Web Broker in this example, but we could also build &lt;a href=&quot;http://wiki.freepascal.org/FPC_and_Apache_Modules&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Apache Modules with Free Pascal&lt;/a&gt;. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I am posting below the code of the TWebModule1 class, which is the core of the Web Broker app. The full source code and executable can be downloaded &lt;a href=&quot;http://sites.google.com/site/yanniel821024/PSP.zip&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. (the code was compiled with Delphi XE2). Note that the code is somewhat messy; this was taken directly from my sandbox. Ah, I copy-pasted (and adjusted) the Pascal Script routines from this example: &lt;a href=&quot;http://lawrencebarsanti.wordpress.com/2009/11/28/introduction-to-pascal-script/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Introduction to Pascal Script&lt;/a&gt;.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;unit WebModuleUnit1;&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;interface&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;uses System.SysUtils, System.Classes, Web.HTTPApp,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RegularExpressions;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;type&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; TWebModule1 = class(TWebModule)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure WebModule1DefaultHandlerAction(Sender: TObject;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { Private declarations }&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { Public declarations }&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function LoadStrFromFile(aFilename: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function ProducePage(aContent: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function ExecPascalScript(const Match: TMatch): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function CompileScript(Script: AnsiString; out Bytecode, Messages: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function RunCompiledScript(Bytecode: AnsiString; out RuntimeErrors: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; WebModuleClass: TComponentClass = TWebModule1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //ScriptOutput is not thread safe.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //ScriptOutput is a global variable.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //We should avoid global variables.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //TODO: Find a better way to store the script output&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ScriptOutput: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; uPSCompiler, uPSRuntime;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;{$R *.dfm}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure Write(P1: Variant);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //This try...except is ugly.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //TODO: Use a conditional checking instead&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScriptOutput:= ScriptOutput + String(P1);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; except&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScriptOutput:= &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure Writeln(P1: Variant);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Write(P1);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ScriptOutput:= ScriptOutput + &#39;&amp;lt;/br&amp;gt;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.LoadStrFromFile(aFilename: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; if not FileExists(aFilename) then Exit;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; with TStringStream.Create do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoadFromFile(aFilename);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= DataString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.ProducePage(aContent: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; RegEx: TRegEx;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ScriptOutput:= &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; aContent:= StringReplace(aContent, #13#10, &#39;&#39;, [rfReplaceAll]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; RegEx.Create(&#39;\&amp;lt;\%(.)*?\%\&amp;gt;&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= regex.Replace(aContent, ExecPascalScript);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.ExecPascalScript(const Match: TMatch): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Bytecode,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Messages,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; RuntimeErrors: AnsiString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; PS: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Bytecode:= &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ScriptOutput:= &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; PS:= Match.Value;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; PS:= StringReplace(PS, &#39;&amp;lt;%&#39;, &#39;&#39;, []);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; PS:= StringReplace(PS, &#39;%&amp;gt;&#39;, &#39;&#39;, []);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; if CompileScript(PS, Bytecode, Messages) then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if RunCompiledScript(Bytecode, RuntimeErrors) then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= ScriptOutput;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function ExtendCompiler(Compiler: TPSPascalCompiler; const Name: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result := True;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compiler.AddDelphiFunction(&#39;procedure Writeln(P1: Variant);&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compiler.AddDelphiFunction(&#39;procedure Write(P1: Variant);&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; except&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := False; // will halt compilation&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.CompileScript(Script: AnsiString; out Bytecode, Messages: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Compiler: TPSPascalCompiler;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; i: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Bytecode:= &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Messages:= &#39;&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Compiler:= TPSPascalCompiler.Create;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Compiler.OnUses:= ExtendCompiler;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= Compiler.Compile(Script) and Compiler.GetOutput(Bytecode);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for i:= 0 to Compiler.MsgCount - 1 do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Length(Messages) = 0 then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Messages:= Compiler.Msg[i].MessageToString&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Messages:= Messages + #13#10 + Compiler.Msg[i].MessageToString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compiler.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure ExtendRuntime(Runtime: TPSExec; ClassImporter: TPSRuntimeClassImporter);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Runtime.RegisterDelphiMethod(nil, @Writeln, &#39;Writeln&#39;, cdRegister);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Runtime.RegisterDelphiMethod(nil, @Write, &#39;Write&#39;, cdRegister);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.RunCompiledScript(Bytecode: AnsiString; out RuntimeErrors: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Runtime: TPSExec;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ClassImporter: TPSRuntimeClassImporter;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Runtime:= TPSExec.Create;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ClassImporter:= TPSRuntimeClassImporter.CreateAndRegister(Runtime, false);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExtendRuntime(Runtime, ClassImporter);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= Runtime.LoadData(Bytecode)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and Runtime.RunScript&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and (Runtime.ExceptionCode = erNoError);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not Result then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RuntimeErrors:=&amp;nbsp; PSErrorToString(Runtime.LastEx, &#39;&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ClassImporter.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Runtime.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; HTMLSource,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; HTMLPascalScriptEmbedded: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //Set up HTMLSource at your convenience&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; HTMLSource:= GetCurrentDir + &#39;\testPage.htm&#39;;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; HTMLPascalScriptEmbedded:= LoadStrFromFile(HTMLSource);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Response.Content:= ProducePage(HTMLPascalScriptEmbedded);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end. &lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/4798569634632094914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/12/pascal-server-pages-script.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4798569634632094914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4798569634632094914'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/12/pascal-server-pages-script.html' title='Pascal Server Pages – Pascal Script'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/NMBn6BjNEW0/default.jpg" height="72" width="72"/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-7571681773818168326</id><published>2011-12-02T23:41:00.009-05:00</published><updated>2012-12-17T20:11:20.982-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><title type='text'>Salary Guide for Delphi developers: Let’s make it</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
If you work as an IT professional in North America, you should probably find very useful the &lt;a href=&quot;http://s3.amazonaws.com/DBM/M3/2011/Downloads/RHT_SalaryGuide_2012.pdf&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;2012 Technology Salary Guide&lt;/a&gt; published by &lt;a href=&quot;http://www.roberthalftechnology.com/Employment-Resources&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Robert Half Technology&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
This guide exposes the compensation trends (salary trends) for pretty much every position in Information Technology. It covers the United States of America and Canada, and you could even obtain salary ranges for particular cities.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
This guide is useful for both managers and non-managers individuals. In my particular case, I am always curious to know if I am getting paid decently.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
The tables below are an excerpt taken from the guide:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;&amp;nbsp;2012 Average Starting Salaries – United States&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: none; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;&quot;&gt;&lt;tbody&gt;
&lt;tr style=&quot;mso-yfti-firstrow: yes; mso-yfti-irow: 0;&quot;&gt;   &lt;td style=&quot;border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
&lt;b&gt;Job Title&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
&lt;b&gt;2011&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
&lt;b&gt;2012&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
&lt;b&gt;% Change&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;tr style=&quot;mso-yfti-irow: 1; mso-yfti-lastrow: yes;&quot;&gt;   &lt;td style=&quot;border-top: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
Software Developer&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
$ 65,750 - $ 104,250 &lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
$ 70,000 - $ 111,000 &lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
6.5%&lt;/div&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;b&gt;2012 Average Starting Salaries – Canada&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: none; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;&quot;&gt;&lt;tbody&gt;
&lt;tr style=&quot;mso-yfti-firstrow: yes; mso-yfti-irow: 0;&quot;&gt;   &lt;td style=&quot;border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
&lt;b&gt;Job Title&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
&lt;b&gt;2011&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
&lt;b&gt;2012&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
&lt;b&gt;% Change&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;tr style=&quot;mso-yfti-irow: 1; mso-yfti-lastrow: yes;&quot;&gt;   &lt;td style=&quot;border-top: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
Software Developer&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
$ 56,250 - $ 94,000 &lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
$ 59,750 - $ 99,750&lt;/div&gt;
&lt;/td&gt;   &lt;td style=&quot;border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;&quot; valign=&quot;top&quot; width=&quot;148&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;&quot;&gt;
6.2%&lt;/div&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
There are further statistics in the guide about Java, .NET, C++, PHP and other programming languages. You can use that info in order to tune the indicators above even more. There are no details about Delphi in this guide.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I think that we (the Delphi community) could gather some statistics about the salary rates for Delphi Developers. I propose running poll surveys to gather such information. Once the polls are closed, we will publish the outcomes and we can draft our conclusions.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The polls are finally closed.&lt;/b&gt; Go to the end of this post and take a look at the outcomes. Thanks a lot to all the participants: 45 in the United States and 30 in Canada. It’s funny how the number of voters was a multiple of 5 in both countries :-) &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;strike&gt;Take a look at the right column of this page: I have published two polls to collect the information about the salary rates in the United States and Canada. I am only putting together the data for these two countries, because I already have some reference data to compare with. (I am referring to the data in the tables above). It would be really nice if someone else could take ownership of similar polls for other countries.&lt;/strike&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;strike&gt;&lt;br /&gt;
&lt;/strike&gt;&lt;br /&gt;
&lt;strike&gt;&lt;b&gt;Important: &lt;/b&gt;&lt;/strike&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strike&gt;I will kindly ask to vote, IF and ONLY IF, you are (were) working as a Delphi Developer in the United States or Canada during the current year 2011. &lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;We could make this better if you enroll your coworkers or any other Delphi developers in your area.&lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;The poll is by nature anonymous: we are just gathering collective information.&lt;/strike&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;strike&gt;&lt;b&gt;Please&lt;/b&gt;, in order for this to work we need your vote!&lt;/strike&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;What’s the salary for a Delphi Developer in the United States?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt; $ 50,000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   5&amp;nbsp; (11%)&lt;br /&gt;
$ 50,000 - $ 60,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  2&amp;nbsp; (4%)&lt;br /&gt;
&amp;gt; $ 60,000 - $ 65,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  1&amp;nbsp; (2%)&lt;br /&gt;
&amp;gt; $ 65,000 - $ 75,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; 7&amp;nbsp; (15%)&lt;br /&gt;
&amp;gt; $ 75,000 - $ 85,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  12&amp;nbsp; (26%)&lt;br /&gt;
&amp;gt; $ 85,000 - $ 95,000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   4&amp;nbsp; (8%)&lt;br /&gt;
&amp;gt; $ 95,000 - $ 105,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; 5&amp;nbsp; (11%)&lt;br /&gt;
&amp;gt; $ 105,000 - $ 115,000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   4&amp;nbsp; (8%)&lt;br /&gt;
&amp;gt; $ 115,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;  5&amp;nbsp; (11%)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;b&gt;What’s the salary for a Delphi Developer in Canada?&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;lt; $ 50,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 6&amp;nbsp; (20%)&lt;br /&gt;
$ 50,000 - $ 60,000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   5&amp;nbsp; (16%)&lt;br /&gt;
&amp;gt; $ 60,000 - $ 65,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  2&amp;nbsp; (6%)&lt;br /&gt;
&amp;gt; $ 65,000 - $ 75,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  3&amp;nbsp; (10%)&lt;br /&gt;
&amp;gt; $ 75,000 - $ 85,000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp; (6%)&lt;br /&gt;
&amp;gt; $ 85,000 - $ 95,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  1&amp;nbsp; (3%)&lt;br /&gt;
&amp;gt; $ 95,000 - $ 105,000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   5&amp;nbsp; (16%)&lt;br /&gt;
&amp;gt; $ 105,000 - $ 115,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  1&amp;nbsp; (3%)&lt;br /&gt;
&amp;gt; $ 115,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  5&amp;nbsp; (16%)</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/7571681773818168326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/12/salary-guide-delphi-2012.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7571681773818168326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7571681773818168326'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/12/salary-guide-delphi-2012.html' title='Salary Guide for Delphi developers: Let’s make it'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-9010127107085875819</id><published>2011-11-30T16:38:00.013-05:00</published><updated>2012-12-13T20:16:47.268-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="iterative"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="recursion"/><category scheme="http://www.blogger.com/atom/ns#" term="recursive"/><title type='text'>Generating Fibonacci numbers in Delphi: Recursive and iterative algorithms</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
In this post, I want to implement a function that returns the Nth Fibonacci number. Initially, I will provide a recursive implementation that derives directly from the Fibonacci sequence definition. Afterwards, I will recode the same function using an iterative approach.&lt;br /&gt;
&lt;br /&gt;
Why do I want to do (share) such a thing? Well, firstly for fun :-) and secondly, because I was asked to do something similar in one phone screen interview. Really? Yep, I was asked to code a function to return the &lt;a href=&quot;http://www.yanniel.info/2011/04/factorial-delphi-recursive-iterative.html&quot; target=&quot;_blank&quot;&gt;factorial of a number&lt;/a&gt; and then, I had to read it over the phone. I implemented the recursive algorithm. At this point, I was asked why I decided to use recursion as opposed to iteration. My answer was that I find the recursive implementation easier (and cleaner) to write. The interviewer finally inquired me about the iterative implementation…&lt;br /&gt;
&lt;br /&gt;
This motivated me to resolve similar programming tasks (recursively and iteratively) just as a training exercise.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Well, enough with that blah, blah, blah. &lt;br /&gt;
&lt;br /&gt;
Taken from &lt;a href=&quot;http://en.wikipedia.org/wiki/Fibonacci_numbers_in_popular_culture&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;: &lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The Fibonacci numbers form a sequence of integers, mathematically defined by&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; F(0)=0; F(1)=1; F(n) = F(n - 1) + F(n - 2) for n &amp;gt; 1.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;This results in the following sequence of numbers:&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ...&lt;/i&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
This simply means that by definition the first Fibonacci number is 0, the second number is 1 and the rest of the Fibonacci numbers are calculated by adding the two previous numbers in the sequence.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Translating that into Delphi code:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;code&gt;function Fibonacci(aNumber: Integer): Integer;&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; if aNumber &amp;lt; 0 then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception.Create(&#39;The Fibonacci sequence is not defined for negative integers.&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; case aNumber of&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; 0: Result:= 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; 1: Result:= 1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; else&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= Fibonacci(aNumber - 1) + Fibonacci(aNumber - 2);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
The function above is the recursive implementation, which in my opinion fits naturally. Now, the iterative implementation might not be as cleaner as that: &lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;code&gt;function Fibonacci(aNumber: Integer): Integer;&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt; var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; I,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; N_1,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; N_2,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; N: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; if aNumber &amp;lt; 0 then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception.Create(&#39;The Fibonacci sequence is not defined for negative integers.&#39;);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; case aNumber of&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0: Result:= 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; 1: Result:= 1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; else&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N_1:= 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N_2:= 1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for I:=2 to aNumber do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N:= N_1 + N_2;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N_1:= N_2;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N_2:= N;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= N;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
Finally, if you want to produce the first 21 Fibonacci numbers try this out:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;code&gt;program Project2;&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; {$APPTYPE CONSOLE}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; {$R *.res}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; uses&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; System.SysUtils;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; I: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; function Fibonacci(aNumber: Integer): Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; {Your implementation goes here}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; for I:=0 to 20 do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(Fibonacci(I));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; Readln;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; end.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
Hopefully you are not bored to death :-)&lt;/div&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/9010127107085875819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/11/fibonacci-numbers-in-delphi.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/9010127107085875819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/9010127107085875819'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/11/fibonacci-numbers-in-delphi.html' title='Generating Fibonacci numbers in Delphi: Recursive and iterative algorithms'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-6674889585497223909</id><published>2011-11-25T18:34:00.008-05:00</published><updated>2012-12-13T20:17:03.276-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Internationalizing your Delphi application: An ABC example</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
If you want to make your Delphi application general enough to address multiple locales, then you need to internationalize it. There are three common aspects that I want to emphasize (no necessarily in that order): &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Resourcing &lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Unit conversions&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Dynamic messages&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
We’ll cover the three of them with a very simple example. Consider the following code snipped intended for the &lt;i&gt;en-US&lt;/i&gt; locale (English-United States of America):&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
procedure TForm1.DefineFever;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; ShowMessage(&#39;If the body temperature rises above 99°F the person is considered to have a fever.&#39;);&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;b&gt;Resourcing&lt;/b&gt; is the process of removing &lt;i&gt;hard-coded strings&lt;/i&gt; from the code by making them &lt;i&gt;resourcestrings &lt;/i&gt;instead.&lt;br /&gt;
&lt;br /&gt;
The code above is not localizable because the &lt;i&gt;ShowMessage &lt;/i&gt;procedure is taking a &lt;i&gt;hard-coded string&lt;/i&gt;. What do you do? Take a look:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
procedure TForm1.DefineFever;&lt;br /&gt;
resourcestring&lt;br /&gt;
&amp;nbsp; strFeverDefinition = &#39;If the body temperature rises above 99°F the person is considered to have a fever.&#39;;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; ShowMessage(strFeverDefinition);&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
We defined &lt;i&gt;strFeverDefinition &lt;/i&gt;as a &lt;i&gt;resourcestring &lt;/i&gt;and used it as a parameter for the &lt;i&gt;ShowMessage&lt;/i&gt; procedure. The functionality remains the same, but the function is now localizable. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Unit conversions&lt;/b&gt;: In some countries (like the United States and Belize) the temperature is given in the Fahrenheit scale, but in the rest is given in the Celsius scale. In order to internationalize this we can do the following:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
function GetFeverTemperature: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;br /&gt;
&amp;nbsp; &lt;/code&gt;&lt;code&gt;LangID&lt;/code&gt;&lt;code&gt;: LangID;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //By default&lt;br /&gt;
&amp;nbsp; Result:= &#39;37.2°C&#39;;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; {read current system locale}&lt;br /&gt;
&amp;nbsp; &lt;/code&gt;&lt;code&gt;LangID&lt;/code&gt;&lt;code&gt; := GetSystemDefaultLangID;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Assuming that only the United States and Belize use the Fahrenheit scale&lt;br /&gt;
&amp;nbsp; if (&lt;/code&gt;&lt;code&gt;LangID&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt; = &lt;/code&gt;&lt;code&gt;{&lt;/code&gt;English - United States&lt;code&gt;}&lt;/code&gt; 1033&lt;code&gt;&lt;/code&gt;&lt;code&gt;) or&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/code&gt;&lt;code&gt;LangID&lt;/code&gt;&lt;code&gt; = &lt;/code&gt;{English - Belize} 10249&lt;code&gt;) then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; Result:= &#39;99°F&#39;;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TForm1.DefineFever;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; ShowMessage(&#39;If the body temperature rises above &#39; + GetFeverTemperature + &#39; the person is considered to have a fever&#39;);&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Wait a minute, we managed the &lt;b&gt;unit conversion&lt;/b&gt; by introducing a &lt;b&gt;dynamic message&lt;/b&gt;, but we reintroduced the &lt;i&gt;hard-coded strings&lt;/i&gt;. That’s not good!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dynamic messages&lt;/b&gt;: We consider the &lt;i&gt;ShowMessage &lt;/i&gt;above to be a &lt;b&gt;dynamic message&lt;/b&gt;, because the parameter depends on the &lt;i&gt;GetFeverTemperature&lt;/i&gt; function, which of course can vary.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
To solve the pitfall above we can refactor the &lt;i&gt;DefineFever &lt;/i&gt;function as follows:&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
procedure TForm1.DefineFever;&lt;br /&gt;
resourcestring&lt;br /&gt;
&amp;nbsp; strFeverDefinition = &#39;If the body temperature rises above %0:s the person is considered to have a fever.&#39;;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; ShowMessage(Format(strFeverDefinition, [GetFeverTemperature]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
We are just using a &lt;i&gt;format string&lt;/i&gt; (&lt;i&gt;resourcestring&lt;/i&gt;) that we can &lt;i&gt;format&lt;/i&gt; by using the &lt;i&gt;Format &lt;/i&gt;routine. This allows &lt;b&gt;resourcing&lt;/b&gt; and handling the &lt;b&gt;dynamic message&lt;/b&gt; all at once.&lt;br /&gt;
&lt;br /&gt;
The thing about &lt;b&gt;dynamic messages&lt;/b&gt; goes beyond. In Spanish, for instance, the &lt;b&gt;dynamic message&lt;/b&gt; would have been coded as follows:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
ShowMessage(&#39;Se considera que la persona tiene fiebre si la temperatura corporal es superior a &#39; + GetFeverTemperature);&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Note that the &lt;i&gt;GetFeverTemperature&lt;/i&gt; is at the end of the &lt;i&gt;ShowMesssage&lt;/i&gt; parameter, as opposed to the English implementation that has it in the middle. There’s no way you can localize something like this if you don’t internationalize it first.&lt;br /&gt;
&lt;br /&gt;
So the ABC for Delphi localization is &lt;b&gt;Resourcing&lt;/b&gt;, &lt;b&gt;Unit Conversions&lt;/b&gt; and &lt;b&gt;Dynamic Messages&lt;/b&gt;.&amp;nbsp; &lt;/div&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/6674889585497223909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/11/internationalization-tips-delphi.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/6674889585497223909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/6674889585497223909'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/11/internationalization-tips-delphi.html' title='Internationalizing your Delphi application: An ABC example'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-3293447750120825928</id><published>2011-11-21T18:34:00.006-05:00</published><updated>2015-10-15T20:22:09.617-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Creational Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><title type='text'>Multiton Design Pattern in Delphi</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
The &lt;i&gt;multiton &lt;/i&gt;is somewhat an extension of the &lt;i&gt;singleton &lt;/i&gt;pattern. It is referred as &lt;i&gt;registry of singletons&lt;/i&gt; by the &lt;a href=&quot;http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;GOF&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612&quot; style=&quot;border: medium none ! important; margin: 0px ! important; padding: 0px ! important;&quot; width=&quot;1&quot; /&gt;. I don’t know for sure who appointed the name &lt;i&gt;multiton&lt;/i&gt;: it’s an analogy derived from the term &lt;i&gt;singleton&lt;/i&gt;. So, &lt;b&gt;singleton &lt;/b&gt;= &lt;b&gt;single &lt;/b&gt;+ &lt;b&gt;ton&lt;/b&gt;; while &lt;b&gt;multiton &lt;/b&gt;= &lt;b&gt;multi &lt;/b&gt;+ &lt;b&gt;ton&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
The &lt;i&gt;singleton&lt;/i&gt; pattern guarantees that a class has only one instance; while the &lt;i&gt;multiton&lt;/i&gt; allows keeping multiple instances by maintaining a map of related keys and unique objects.&amp;nbsp; Note that there can be only one instance per key when implementing the &lt;i&gt;multiton&lt;/i&gt; pattern. Also, note that the key does not have to be a string value; it can be an object for example. Nonetheless, in our code sniped we will consider the key to be a string.&lt;br /&gt;
&lt;br /&gt;
I am going to tweak my &lt;a href=&quot;http://www.yanniel.info/2010/10/singleton-pattern-delphi.html&quot; target=&quot;_blank&quot; title=&quot;Implementing the Singleton Design Pattern in Delphi without Global Variables&quot;&gt;singleton class implementation&lt;/a&gt; so that I can make it a &lt;i&gt;multiton&lt;/i&gt; instead:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
unit Multiton;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; Generics.Collections;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TMultiton = class&lt;br /&gt;
&amp;nbsp; private&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Private fields and methods here...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; class var _registry: TDictionary&amp;lt;string, TMultiton&amp;gt;;&lt;br /&gt;
&amp;nbsp; protected&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function Create(aName: string): TMultiton;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class destructor Destroy;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function Lookup(aName: string): TMultiton;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Other public methods and properties here...&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ TMultiton }&lt;br /&gt;
&lt;br /&gt;
class function TMultiton.Create(aName: string): TMultiton;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if not Assigned(_registry) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry:= TDictionary&amp;lt;string, TMultiton&amp;gt;.Create;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if not _registry.TryGetValue(aName, Result) then&lt;br /&gt;
&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= inherited Create as Self;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.Add(aName, Result);&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class destructor TMultiton.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp; if Assigned(_registry) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.Values.ToArray[0].Free;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class function TMultiton.Lookup(aName: string): TMultiton;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if Assigned(_registry) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.TryGetValue(aName, Result);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TMultiton.Destroy;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; _instance: TMultiton;&lt;br /&gt;
&amp;nbsp; ValuesArray: TArray&amp;lt;TMultiton&amp;gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if Assigned(_registry) then&lt;br /&gt;
&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ValuesArray:= _registry.Values.ToArray;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.Clear;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry:= nil;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for _instance in&amp;nbsp; ValuesArray do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if _instance &amp;lt;&amp;gt; Self then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _instance.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; inherited;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
A few things I want you to note:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Instead of a single instance, we are holding a registry of instances. We do so by introducing the class variable &lt;i&gt;&lt;b&gt;_registry&lt;/b&gt;&lt;/i&gt; of type &lt;i&gt;&lt;b&gt;TDictionary&amp;lt;string, TMultiton&amp;gt;&lt;/b&gt;&lt;/i&gt;. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;We register (create) the different instances by calling the class function &lt;i&gt;&lt;b&gt;Create&lt;/b&gt;&lt;/i&gt;. This function gets the key name as a parameter. A new instance is only created if no matches to the key name are found in the dictionary. If a match is found, then the corresponding value is returned from the dictionary data structure.&lt;/li&gt;
&lt;li&gt;The &lt;i&gt;&lt;b&gt;Lookup &lt;/b&gt;&lt;/i&gt;class function allows retrieving a particular instance by giving its key name. Note that the &lt;i&gt;&lt;b&gt;Create &lt;/b&gt;&lt;/i&gt;function can also be used for this purpose, but it feels more natural to call &lt;i&gt;&lt;b&gt;Lookup &lt;/b&gt;&lt;/i&gt;for the searches, and &lt;i&gt;&lt;b&gt;Create &lt;/b&gt;&lt;/i&gt;for the registration (creation) of instances.&lt;/li&gt;
&lt;li&gt;We have provided a regular destructor that once invoked releases all the memory: not only the current &lt;i&gt;multiton&lt;/i&gt; instance, but the whole registry.&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/li&gt;
&lt;li&gt;We have also provided a class destructor in case that we forget to manually release the memory. &amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
This code was compiled with Delphi XE2, but it should also work for all versions above Delphi 2009. Comments, corrections and suggestions are most welcome.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Consider reading these books about design patterns if you haven’t yet:&lt;/div&gt;
&lt;br /&gt;
&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=lmaoookaiie-20&amp;marketplace=amazon&amp;region=US&amp;placement=0596007124&amp;asins=0596007124&amp;linkId=PILQCWZU7WENR3F6&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=lmaoookaiie-20&amp;marketplace=amazon&amp;region=US&amp;placement=0201633612&amp;asins=0201633612&amp;linkId=S276LENJUNFY3V7F&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=lmaoookaiie-20&amp;marketplace=amazon&amp;region=US&amp;placement=0321213351&amp;asins=0321213351&amp;linkId=C32AUAPTKLUF5S62&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/3293447750120825928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/11/multiton-design-pattern-delphi.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/3293447750120825928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/3293447750120825928'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/11/multiton-design-pattern-delphi.html' title='Multiton Design Pattern in Delphi'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-9091275202019482691</id><published>2011-11-03T11:18:00.015-04:00</published><updated>2012-12-13T20:17:53.656-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Dependency Injection in Delphi: a simple example</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I want to give a fairly simple Delphi example that will expose the dependency injection pattern. No framework, no third-party library will be needed here: just plain Delphi code.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I won’t dig into the&lt;a href=&quot;http://martinfowler.com/articles/injection.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot; title=&quot;Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern&quot;&gt; different forms of dependency injection&lt;/a&gt;. I will explain the idea of the pattern as simple as possible.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Instead of giving you bunch of definitions, I will present you with some code. The need to inject a dependency will come naturally. You’ll see:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;type&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; IDependency = interface&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; [&#39;{618030A2-DB17-4532-81D0-D5AA6F73DC66}&#39;]&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; TDependencyA = class(TInterfacedObject, IDependency)&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; TDependencyB = class(TInterfacedObject, IDependency)&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;TConsumer = class&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FDependency: IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(aDependencyClassName: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure GetDependencyType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;{ TDependencyA }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;procedure TDependencyA.GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; WriteLn(&#39;Instance of type TDependencyA&#39;);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;{ TDependencyB }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;procedure TDependencyB.GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; WriteLn(&#39;Instance of type TDependencyB&#39;);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;{ TConsumer }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;constructor TConsumer.Create(aDependencyClassName: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; if aDependencyClassName = &#39;TDependencyA&#39;&amp;nbsp; then&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FDependency:= TDependencyA.Create&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; else if aDependencyClassName = &#39;TDependencyB&#39;&amp;nbsp; then&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FDependency:= TDependencyB.Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;procedure TConsumer.GetDependencyType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; if FDependency &amp;lt;&amp;gt; nil then&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FDependency.GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
It is a good and recommended practice in OOP to decrease coupling as much as possible. This means that each component (class) should avoid knowing implementation details of the other components (classes).&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
In our example, the &lt;i&gt;TConsumer&lt;/i&gt; class has a dependency of type &lt;i&gt;IDependency&lt;/i&gt;. So far so good, since we are abstracting any implementation specifics by using an interface (contract). The problem becomes obvious when you take a look at the constructor of &lt;i&gt;TConsumer&lt;/i&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;i&gt;TConsumer.Create&lt;/i&gt; is instantiating the concrete classes &lt;i&gt;TDependencyA&lt;/i&gt;&amp;nbsp;&amp;nbsp; or &lt;i&gt;TDependencyB &lt;/i&gt;depending on the string parameter &lt;i&gt;aDependencyClassName&lt;/i&gt;. As you can see, the design is not well decupled here, because the consumer class (&lt;i&gt;TConsumer&lt;/i&gt;) is hard-coding implementation details about its dependency.&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The question is: can we decuple this design even more? Yes, the dependency injection pattern will do it for us.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
It’s now time to refactor our code a little bit. We’ll start by changing the signature of the constructor of the &lt;i&gt;TConsumer &lt;/i&gt;class:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;constructor TConsumer.Create(aDependency: IDependency);&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; FDependency:= aDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Instead of choosing the concrete dependency to instantiate within the constructor, we are now injecting the dependency trough the aDependency parameter. Now the class &lt;i&gt;TConsumer&lt;/i&gt; is completely independent of the dependency concrete class.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Ok, ok, but we still need to create the concrete dependency instance somewhere, right? Yes, we do. For that we will create a new class &lt;i&gt;TDependencyInjector &lt;/i&gt;whose only purpose is to return the right dependency instance. This class will use reflection in order to create the right instance of &lt;i&gt;IDependency&lt;/i&gt;. It will use just a string parameter that contains the dependency class name. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; RTTI,&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; Dependencies;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;type&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; TDependencyInjector =&amp;nbsp; class&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class function GetDependency(aDependencyClassName: string): IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;{ TDependencyInjector }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;class function TDependencyInjector.GetDependency(aDependencyClassName: string): IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; RttiContext: TRttiContext;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; RttiType: TRttiInstanceType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; RttiType := RttiContext.FindType(aDependencyClassName) as TRttiInstanceType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; if RttiType &amp;lt;&amp;gt; nil then&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= RttiType.GetMethod(&#39;Create&#39;).Invoke(RttiType.MetaclassType, []).AsInterface as IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Finally, let&#39;s put all the pieces together. Consider this console application that puts all the pieces in place:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;program DependencyInjection;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;{$APPTYPE CONSOLE}&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;{$R *.res}&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;...&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; SomeConsumerObj: TConsumer;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; Dependency: IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; Dependency:= TDependencyInjector.GetDependency(&#39;Dependencies.TDependencyA&#39;);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; //Dependency:= TDependencyInjector.GetDependency(&#39;Dependencies.TDependencyB&#39;);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; SomeConsumerObj:= TConsumer.Create(Dependency);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeConsumerObj.GetDependencyType;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeConsumerObj.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
In the code above we get the &lt;i&gt;Dependency &lt;/i&gt;instance at runtime by using the &lt;i&gt;TDependencyInjector &lt;/i&gt;class. Then we inject that dependency using the constructor of the class&amp;nbsp; &lt;i&gt;TConsumer&lt;/i&gt;. We have got a more decoupled design by using dependency injection. Don&#39;t you agree? ;-)&lt;br /&gt;
&lt;br /&gt;
Get the full source code of this example &lt;a href=&quot;http://sites.google.com/site/yanniel821024/DependencyInjection.rar&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; (written in Delphi XE 2).&lt;/div&gt;&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/9091275202019482691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/11/dependency-injection-in-delphi.html#comment-form' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/9091275202019482691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/9091275202019482691'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/11/dependency-injection-in-delphi.html' title='Dependency Injection in Delphi: a simple example'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-7893425994171877967</id><published>2011-09-22T12:25:00.023-04:00</published><updated>2015-10-15T20:10:41.397-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computers"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Structural patterns"/><title type='text'>Decorator Design Pattern in Delphi. Multiple Decorations</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
In my &lt;a href=&quot;http://www.yanniel.info/2011/08/decorator-pattern-delphi-single.html&quot; title=&quot;Decorator Pattern in Delphi. Single decoration&quot;&gt;previous post&lt;/a&gt; I introduced the decorator design pattern to you. I used a fairly simple example (a silly example if you wish) in order to give you a flavour of the pattern. I wrote Delphi code for that matter and I focused in having ONE, and only ONE, decorator class.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
This was the situation in the original example: we implemented a &lt;b&gt;TConsole&lt;/b&gt; class with a &lt;i&gt;Write &lt;/i&gt;method that writes a text to the standard output. Then, we used a &lt;b&gt;TUpperCaseConsole&lt;/b&gt; class to decorate a &lt;b&gt;TConsole&lt;/b&gt; object. The decoration itself was simple: uppercasing the text to be shown.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Now I want to add a second decoration, which is &lt;i&gt;framing &lt;/i&gt;the text to be shown within a rectangle of asterisks (*). For that I will create a new decorator class: &lt;b&gt;TFramedConsole&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Let’s present a raw piece of code: (We will refine and refactor the code later)&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole: TConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TConsole.Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TUpperCaseConsole.Create(MyConsole); //first decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //second decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write(&#39;Hello World!&#39;);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
In the code above we added a second decoration. The output for that code should be something like this: &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;**&amp;nbsp;&amp;nbsp; HELLO WORLD!&amp;nbsp;&amp;nbsp; **&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b&gt;This is cool:&lt;/b&gt; We can even add the same decoration several times. For example, to provide a double frame we would do something like this:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole: TConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TConsole.Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TUpperCaseConsole.Create(MyConsole); //first decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //second decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //third decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write(&#39;Hello World!&#39;);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Can you guess the output now? It’s like this:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;**&amp;nbsp;&amp;nbsp; HELLO WORLD!&amp;nbsp;&amp;nbsp; **&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;**********************&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
How are the decorated and decorator classes put together when multiple decorations are needed? There are two key things to remember:&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;The different concrete decorators (&lt;b&gt;TUpperCaseConsole&lt;/b&gt; and &lt;b&gt;TFramedConsole&lt;/b&gt;) must inherit from a base decorator class. We will introduce the &lt;b&gt;TDecoratedConsole &lt;/b&gt;class as the common ancestor for our decorators. &lt;/li&gt;
&lt;li&gt;The base decorator class forwards the calls to its &lt;i&gt;Write &lt;/i&gt;method to the decorated object’s &lt;i&gt;Write&lt;/i&gt; method. &lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The code looks like this:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;interface&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; SysUtils, Windows;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;type&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TConsole = class&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FText: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); virtual;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TDecoratedConsole = class(TConsole)  //Base Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FConsole: TConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(aConsole: TConsole);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TUpperCaseConsole = class(TDecoratedConsole) //Concrete Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TFramedConsole = class(TDecoratedConsole)    //Concrete Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure CreateFrame(var aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;{ TConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; FText:= aText;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; Writeln(FText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;{ TDecoratedConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;constructor TDecoratedConsole.Create(aConsole: TConsole);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; inherited Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; FConsole:= aConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;destructor TDecoratedConsole.Destroy;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; FConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; inherited;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TDecoratedConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; FConsole.Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;{ TUpperCaseConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TUpperCaseConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; aText:= UpperCase(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; inherited Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;{ TFramedConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TFramedConsole.CreateFrame(var aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TextLength: Integer;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; AsteriskLine: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; RealText: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; if Pos(&#39;*&#39;, aText) = 0 then&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aText:= &#39;**   &#39; +  aText + &#39;   **&#39;;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; RealText:= Trim(StringReplace(aText, &#39;*&#39;, &#39;&#39;, [rfReplaceAll]));&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TextLength:= Length(RealText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; AsteriskLine:= StringOfChar(&#39;*&#39;, TextLength + 10);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; aText:= AsteriskLine    + #13#10 +&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aText        + #13#10 + AsteriskLine;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TFramedConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; CreateFrame(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; inherited Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
I know you are dying to say: &lt;i&gt;the code above is awful because the decorators are bounded to a specific implementation of the decorated class&lt;/i&gt;. Indeed, we are going to fix that by introducing a &lt;b&gt;TAbstractConsole &lt;/b&gt;class, which will be the common ancestor of the decorated and decorator classes.  The &lt;b&gt;TAbstractConsole &lt;/b&gt;class is &lt;i&gt;abstract&lt;/i&gt;, meaning it has no implementation. You could have used an &lt;i&gt;Interface &lt;/i&gt;type instated, something like &lt;b&gt;IAbstractConsole&lt;/b&gt;. I’ll leave that to you.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Finally, I present you the consuming code plus the class definition code:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;//Consuming code&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole: TAbstractConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TConsole.Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TUpperCaseConsole.Create(MyConsole); //first decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //second decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //third decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write(&#39;Hello World!&#39;);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;//Class definition code&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;interface&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; SysUtils, Windows;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;type&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TAbstractConsole = class           //Abstract class ==&amp;gt; Interface&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string);  virtual; abstract;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TConsole = class(TAbstractConsole) //Concrete class&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FText: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TDecoratedConsole = class(TAbstractConsole)  //Base Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FConsole: TAbstractConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(aConsole: TAbstractConsole);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TUpperCaseConsole = class(TDecoratedConsole) //Concrete Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TFramedConsole = class(TDecoratedConsole)    //Concrete Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure CreateFrame(var aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;{ TConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; FText:= aText;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; Writeln(FText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;{ TDecoratedConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;constructor TDecoratedConsole.Create(aConsole: TAbstractConsole);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; inherited Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; FConsole:= aConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;destructor TDecoratedConsole.Destroy;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; FConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; inherited;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TDecoratedConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; FConsole.Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;{ TUpperCaseConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TUpperCaseConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; aText:= UpperCase(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; inherited Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;{ TFramedConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TFramedConsole.CreateFrame(var aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TextLength: Integer;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; AsteriskLine: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; RealText: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; if Pos(&#39;*&#39;, aText) = 0 then&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aText:= &#39;**   &#39; +  aText + &#39;   **&#39;;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; RealText:= Trim(StringReplace(aText, &#39;*&#39;, &#39;&#39;, [rfReplaceAll]));&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; TextLength:= Length(RealText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; AsteriskLine:= StringOfChar(&#39;*&#39;, TextLength + 10);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; aText:= AsteriskLine    + #13#10 +&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aText        + #13#10 + AsteriskLine;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;procedure TFramedConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; CreateFrame(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; inherited Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I hope this was useful and I am definitely waiting for you feedback. Corrections and suggestions are welcome in the comment section below. Thanks!&lt;br /&gt;
&lt;br /&gt;
For further reading about design patterns get your hands on these classics:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;font-family: inherit;&quot;&gt;
&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=lmaoookaiie-20&amp;marketplace=amazon&amp;region=US&amp;placement=0596007124&amp;asins=0596007124&amp;linkId=PILQCWZU7WENR3F6&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=lmaoookaiie-20&amp;marketplace=amazon&amp;region=US&amp;placement=0201633612&amp;asins=0201633612&amp;linkId=S276LENJUNFY3V7F&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=lmaoookaiie-20&amp;marketplace=amazon&amp;region=US&amp;placement=0321213351&amp;asins=0321213351&amp;linkId=C32AUAPTKLUF5S62&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/7893425994171877967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/09/decorator-design-pattern-in-delphi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7893425994171877967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7893425994171877967'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/09/decorator-design-pattern-in-delphi.html' title='Decorator Design Pattern in Delphi. Multiple Decorations'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-75425698973535468</id><published>2011-08-26T12:48:00.017-04:00</published><updated>2015-10-15T20:14:09.060-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computers"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Structural patterns"/><title type='text'>Decorator Design Pattern in Delphi. Single decoration</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Decorator (also referred as Wrapper) is classified by &lt;a href=&quot;http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;GoF&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612&quot; height=&quot;1&quot; style=&quot;border: none !important; margin: 0px !important; padding: 0px !important;&quot; width=&quot;1&quot; /&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612&quot; height=&quot;1&quot; style=&quot;border: none !important; margin: 0px !important; padding: 0px !important;&quot; width=&quot;1&quot; /&gt;as a structural pattern. Its purpose is to:&lt;br /&gt;
&lt;br /&gt;
“Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.”&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Both inheritance and the decorator pattern aim towards extending the functionality. This is what they have in common. &lt;br /&gt;
&lt;br /&gt;
There are a couple of remarkable differences:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Inheritance extends the functionality at compilation time (statically). The decorator pattern extends the functionality at runtime (dynamically).&lt;/li&gt;
&lt;li&gt;Inheritance extends the functionality of a whole class (all objects of the extended class get the extended functionality). The decorator pattern allows extending the functionality of a selected object (or group of objects) without affecting the remaining objects.&amp;nbsp;&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
You can think of the decorator pattern as a way to add make-up to an object or even as a way to attach accessories to that object. All this is done on the fly after the object itself has been created.&lt;br /&gt;
&lt;br /&gt;
Let’s walk through a simple task to get the idea. This example might sound silly. I want it silly so that you can focus on the decorator implementation, avoiding any extra complexity.&lt;br /&gt;
&lt;br /&gt;
Please, be aware that this design is somewhat unfinished, since we are only covering the case for a single decoration (just one functionality to be extended). In real life, we will need multiple decorators in order to add multiple responsibilities. As this is a controlled example (just for the purpose of this discussion), I am enforcing that only ONE responsibility is going to be extended. This means, we will have ONE decorator class. Because of that, I have made some &lt;i&gt;simplifications &lt;/i&gt;to the design; so that you get a &lt;i&gt;taste &lt;/i&gt;of the decorator pattern in its simplest expression.&lt;br /&gt;
&lt;br /&gt;
Later on, in &lt;a href=&quot;http://www.yanniel.info/2011/09/decorator-design-pattern-in-delphi.html&quot; title=&quot;Decorator Pattern in Delphi. Multiple Decorations&quot;&gt;other post&lt;/a&gt;, we’ll see how to add multiple responsibilities (with multiple decorator classes). For that, we’ll need a more complex design to overcome the shortcomings of this initial example. For now, just get the idea...we&#39;ll come back later to the multiple decorations scenario.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;i&gt;If you get some time, take a look at the discussion in the comments section.&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Subtask 1: &lt;/b&gt;Let’s create a &lt;i&gt;TConsole&lt;/i&gt; class which purpose is to output a given text to the standard output. The code might be something like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
interface&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TConsole = class&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string);&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
procedure TConsole.Write(aText: string);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Writeln(aText);&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;b&gt;Subtask 2:&lt;/b&gt; Let’s use the &lt;i&gt;TConsole&lt;/i&gt; class to printout “Hello World!”. The following code snipped does it:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; MyConsole: TConsole; &lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; MyConsole:= TConsole.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write(&#39;Hello World!&#39;);&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; Readln;&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
This is how the output looks like:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: black; color: white;&quot;&gt;Hello World!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Subtask 3:&lt;/b&gt; Now, let’s decorate the object referenced by &lt;i&gt;MyConsole &lt;/i&gt;(only that object, not the whole class). What I want is to upper case every text to be printed out. We need to define a decorator class &lt;i&gt;TUpperCaseConsole&lt;/i&gt; for that purpose. See the code:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; SysUtils;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TConsole = class&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); virtual;&lt;br /&gt;
&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;nbsp; //Decorator &lt;br /&gt;
&amp;nbsp; TUpperCaseConsole = class(TConsole)&lt;br /&gt;
&amp;nbsp; private&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; FConsole: TConsole;&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(aConsole: TConsole);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ TConsole }&lt;br /&gt;
&lt;br /&gt;
procedure TConsole.Write(aText: string);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Writeln(aText);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{ TUpperCaseConsole }&lt;br /&gt;
&lt;br /&gt;
constructor TUpperCaseConsole.Create(aConsole: TConsole);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; inherited Create;&lt;br /&gt;
&amp;nbsp; FConsole:= aConsole;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TUpperCaseConsole.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; FConsole.Free;&lt;br /&gt;
&amp;nbsp; inherited;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TUpperCaseConsole.Write(aText: string);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; aText:= UpperCase(aText);&lt;br /&gt;
&amp;nbsp; &lt;/code&gt;&lt;code&gt;FConsole.&lt;/code&gt;&lt;code&gt;Write(aText);&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Notice in the code above that the decorator class (&lt;i&gt;TUpperCaseConsole&lt;/i&gt;) inherits from the decorated class (&lt;i&gt;TConsole&lt;/i&gt;). This makes both the decorated and the decorator objects to share the same public interface. Furthermore, the &lt;i&gt;TUpperCaseConsole &lt;/i&gt;class &lt;i&gt;Has-A&lt;/i&gt; field of the &lt;i&gt;TConsole&lt;/i&gt; type. We’ll use this field to forward the printing functionality to the &lt;i&gt;TConsole&lt;/i&gt; class, once we have applied the cosmetic (upper case transformation) to the text.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Subtask 4:&lt;/b&gt; Let’s now create some consuming code to decorate one &lt;i&gt;TConsole&lt;/i&gt; object on the fly. Note how the &lt;i&gt;TUpperCaseConsole &lt;/i&gt;constructor wraps (decorates) the object referenced by &lt;i&gt;MyConsole&lt;/i&gt;.&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; MyConsole: TConsole;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; MyConsole:= TConsole.Create;&lt;br /&gt;
&amp;nbsp; MyConsole:= TUpperCaseConsole.Create(MyConsole);&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write(&#39;Hello World!&#39;);&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; Readln;&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
This is how the output looks like after the decorator has been applied:&lt;span style=&quot;background-color: black; color: white;&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: black; color: white;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: black; color: white;&quot;&gt;HELLO WORLD!&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
In real life, you’ll have to judge whether the decorator pattern is the best alternative to be applied to solve a particular problem. Not always it the right way to go with. For more details get your hands on these classic books.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0596007124&amp;amp;asins=0596007124&amp;amp;linkId=PILQCWZU7WENR3F6&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;

&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0201633612&amp;amp;asins=0201633612&amp;amp;linkId=S276LENJUNFY3V7F&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;

&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0321213351&amp;amp;asins=0321213351&amp;amp;linkId=C32AUAPTKLUF5S62&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/75425698973535468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/08/decorator-pattern-delphi-single.html#comment-form' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/75425698973535468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/75425698973535468'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/08/decorator-pattern-delphi-single.html' title='Decorator Design Pattern in Delphi. Single decoration'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-5385986656053172403</id><published>2011-08-19T13:25:00.013-04:00</published><updated>2012-12-13T20:18:57.976-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computers"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Anonymous Methods in Delphi</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Under the scope of Delphi, an &lt;b&gt;anonymous method&lt;/b&gt; is either a &lt;i&gt;procedure &lt;/i&gt;or &lt;i&gt;function &lt;/i&gt;that’s unattached to an identifier. In other words, &lt;a href=&quot;http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/anonymousmethods_xml.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;anonymous methods&lt;/a&gt; don’t have names, which is why they are called “anonymous”.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Basically, you can assign a block of code (in the form of a &lt;i&gt;procedure &lt;/i&gt;or &lt;i&gt;function&lt;/i&gt;) directly to a variable.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I am going to give you a simplistic example. I am going to &lt;i&gt;Keep it simple, Stupid!&lt;/i&gt; to avoid distracting you with any complexity. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
This is the wording of the task: create a console application which prints “Hello world” and “Good bye” to the standard output. Constraint: use the &lt;i&gt;Writeln &lt;/i&gt;function just once in the code.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
To accomplish such reckless task in the old days (before the introduction of &lt;b&gt;anonymous methods&lt;/b&gt;) you could do this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
program Project1;&lt;br /&gt;
&lt;br /&gt;
{$APPTYPE CONSOLE}&lt;br /&gt;
&lt;br /&gt;
procedure PrintString(aText: string);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp;Writeln(aText);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; PrintString(&#39;Hello world&#39;);&lt;br /&gt;
&amp;nbsp; PrintString(&#39;Good bye&#39;);&lt;br /&gt;
&amp;nbsp; Readln;&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
How to do the same with &lt;b&gt;anonymous methods&lt;/b&gt;? Take a look at the following code:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
program Project1;&lt;br /&gt;
&lt;br /&gt;
{$APPTYPE CONSOLE}&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TMyAnonymousProcedureType = reference to procedure(aText: string);&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; A: TMyAnonymousProcedureType;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; A:= procedure(aText: string) //No semicolon here&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(aText);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; A(&#39;Hello world&#39;);&lt;br /&gt;
&amp;nbsp; A(&#39;Good bye&#39;);&lt;br /&gt;
&amp;nbsp; Readln;&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
As you can see in the example above, we have assigned code directly to the variable &lt;i&gt;A&lt;/i&gt;. Then, we called &lt;i&gt;A&lt;/i&gt; with parameters, and Voilà!: we have accomplished our reckless task with &lt;b&gt;anonymous methods&lt;/b&gt; as well.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Pay attention to this:&amp;nbsp; if you are tented to declare variable &lt;i&gt;A&lt;/i&gt; like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; A: reference to procedure(aText: string);&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Don’t! That shortcut doesn’t work. You’ll get a compilation error…like this:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Undeclared identifier: ‘reference’&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
So, you do need to declare:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
type&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp; TMyAnonymousProcedureType = reference to procedure(aText: string);&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Only later you can define the type of variable &lt;i&gt;A&lt;/i&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
You might be asking by now: why to bother with all this? What&#39;s the benefit&lt;b&gt;&lt;/b&gt;? Well, in the previous example there’s little or none benefit present.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Generally speaking, &lt;b&gt;anonymous methods&lt;/b&gt; are handy in the following cases:&lt;/div&gt;
&lt;ul style=&quot;text-align: justify;&quot;&gt;
&lt;li&gt;You have been trying to name a local method for hours. You cannot think of a name for it. Well, think no more: use &lt;b&gt;anonymous methods&lt;/b&gt;. Don’t put a tasteless name like &lt;i&gt;Foo()&lt;/i&gt;, &lt;i&gt;XXX()&lt;/i&gt;, &lt;i&gt;Aux&lt;/i&gt;(), etc.&lt;/li&gt;
&lt;li&gt;You create a function that is called just once(it’s just called from one spot).&lt;/li&gt;
&lt;li&gt;You can use &lt;b&gt;anonymous methods&lt;/b&gt; to provide elegant and simpler implementations. This is the case when combining &lt;b&gt;generics types&lt;/b&gt; with &lt;b&gt;anonymous methods&lt;/b&gt; for example. I should write about this shortly. Subscribe to my feed and stay tuned :-)&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
With this post I wanted to introduce &lt;b&gt;anonymous methods&lt;/b&gt; to you. It’s OK if you don’t see the benefits clearly right now. You’ll get there :-)&lt;/div&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/5385986656053172403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/08/anonymous-methods-in-delphi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/5385986656053172403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/5385986656053172403'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/08/anonymous-methods-in-delphi.html' title='Anonymous Methods in Delphi'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-4390956600548964998</id><published>2011-08-15T12:11:00.010-04:00</published><updated>2012-12-13T20:19:17.864-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Computers"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Hide the utter &quot;Create&quot; constructor of TObject in Delphi</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
In Delphi, constructors can be inherited; this doesn’t happen in Java, C# and C++ for example. Furthermore, constructors in Delphi can have multiple and different names; usually they are called &lt;b&gt;Create&lt;/b&gt;, but this is just a convention, since you can define a constructor with whatever name you choose.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
In addition to all this, all classes in Delphi inherit ultimately from &lt;b&gt;TObject&lt;/b&gt;, which contains a &lt;i&gt;public&lt;/i&gt; parameterless constructor, named &lt;b&gt;Create&lt;/b&gt;.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Due to the facts above, it‘s easy to understand that all classes in Delphi have a &lt;i&gt;public&lt;/i&gt; &lt;b&gt;Create &lt;/b&gt;parameterless constructor, that has been inherited from &lt;b&gt;TObject&lt;/b&gt;. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I am not going to discuss here whether this is bad or good. What I want to show you is a way to hide the &lt;i&gt;public&lt;/i&gt; &lt;b&gt;Create &lt;/b&gt;parameterless constructor of &lt;b&gt;TObject&lt;/b&gt; in case you need to do so.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;b style=&quot;color: red;&quot;&gt;Burn this out&lt;/b&gt;: you cannot hide any member (field, method, constructor, destructor) in Delphi by decreasing the level of visibility. If a member in a superclass is &lt;i&gt;public&lt;/i&gt;, you cannot hide it in a child class by changing the visibility to &lt;i&gt;protected&lt;/i&gt; or &lt;i&gt;private&lt;/i&gt;. Once &lt;i&gt;public&lt;/i&gt; you are always &lt;i&gt;public&lt;/i&gt;. This means, you cannot hide the &lt;i&gt;public&lt;/i&gt; &lt;b&gt;Create &lt;/b&gt;parameterless constructor of &lt;b&gt;TObject&lt;/b&gt; by lowering its visibility in an inheriting class. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
So, how can we hide the &lt;b&gt;Create &lt;/b&gt;constructor of &lt;b&gt;TObject&lt;/b&gt;? Is there even a way for doing so? Yes, there is a way. We came to the solution in the LinkedIn’s  &lt;i&gt;Delphi Professionals&lt;/i&gt; group. I thought it would be worthy to share this with the rest of the Delphi community.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Basically, you can hide the &lt;i&gt;public&lt;/i&gt; &lt;b&gt;Create &lt;/b&gt;parameterless constructor of &lt;b&gt;TObject&lt;/b&gt; with another &lt;i&gt;public&lt;/i&gt; method having the same &lt;b&gt;Create &lt;/b&gt;name. For example:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;u&gt;Class definition snipped&lt;/u&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;TSomeClass = class(TObject)&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;//this constructor takes two parameters, and hides the TObject.Create()&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;constructor Create(aParameter1: string; aParameter2: Integer ); &lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;u&gt;Consuming code snipped&lt;/u&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; SomeObject: TSomeClass;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; SomeObject:= TSomeClass.Create; //This does not compile!&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; //This compiles. Uncomment and try...&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; // SomeObject:= TSomeClass.Create(&#39;Hello People!&#39;, 12);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //TODO&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeObject.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
See, in the code above the &lt;b&gt;TObject.Create()&lt;/b&gt; has been hidden :-) &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
There is another consideration though: What happens if we &lt;i&gt;overload &lt;/i&gt;the &lt;b&gt;Create &lt;/b&gt;constructor?&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;TSomeClass = class(TObject)&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; //this one takes two parameters, and hides the TObject.Create()&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; constructor Create(aParameter1: string; aParameter2: Integer ); overload;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; constructor Create(aThisTakesAChar: Char); overload;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; constructor Create(aThisTakesAnInteger: Integer); overload;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
By overloading the &lt;b&gt;Create &lt;/b&gt;constructor we have made the &lt;b&gt;TObject.Create()&lt;/b&gt; visible again. If we want to keep it hidden, then we should avoid overloading. For that, you can simply use a different name for the new constructors being added. Something like this:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;TSomeClass = class(TObject)&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;public&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; //this one takes two parameters, and hides the TObject.Create()&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; constructor Create(aParameter1: string; aParameter2: Integer );&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; constructor Create2(aThisTakesAChar: Char); &lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; constructor Create3(aThisTakesAnInteger: Integer); &lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Now the &lt;b&gt;TObject.Create() &lt;/b&gt;constructor is hidden again.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;u&gt;Consuming code&lt;/u&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; SomeObject: TSomeClass;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; SomeObject:= TSomeClass.Create; //This does not compile!&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; //This compiles. Uncomment and try...&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; // SomeObject:= TSomeClass.Create(&#39;Hello People!&#39;, 12);&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; //This compiles. Uncomment and try...&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; // SomeObject:= TSomeClass.Create1(&#39;H&#39;); &lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; //This compiles. Uncomment and try...&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; // SomeObject:= TSomeClass.Create2(12); &lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //TODO&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeObject.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;
Why would someone want to hide the &lt;b&gt;TObject.Create()&lt;/b&gt; anyway? It depends on the situation. I have found this very useful when implementing a singleton class in Delphi. For details refer to: &lt;a href=&quot;http://www.yanniel.info/2010/10/singleton-pattern-delphi.html&quot;&gt;Singleton class in Delphi&lt;/a&gt;.&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
As a conclusion, you can hide the &lt;b&gt;TObject.Create()&lt;/b&gt; constructor by defining a new &lt;i&gt;public&lt;/i&gt; method with the name &lt;b&gt;Create &lt;/b&gt;in the inheriting class. You cannot hide &lt;b&gt;TObject.Create()&lt;/b&gt; by lowering the visibility to &lt;i&gt;protected&lt;/i&gt;, &lt;i&gt;private&lt;/i&gt;, etc.&lt;/div&gt;&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/4390956600548964998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/08/hide-tobject-create-constructor-delphi.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4390956600548964998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4390956600548964998'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/08/hide-tobject-create-constructor-delphi.html' title='Hide the utter &quot;Create&quot; constructor of TObject in Delphi'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-3590725687895298113</id><published>2011-08-07T18:59:00.012-04:00</published><updated>2012-12-17T20:11:53.640-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>My contributions to the Delphi community at RosettaCode</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;a href=&quot;http://rosettacode.org/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;RosettaCode&lt;/a&gt; is a wiki site that gathers a collection of programming tasks being resolved in as many programming languages as possible.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
You can post solutions to a particular task using a particular language (Delphi, Java, C++, C#, Ruby, the list goes and goes).&amp;nbsp; All solutions to the same task are coded in the same page, allowing a fast knowledge transfer from one language to the other. Also, you can compare how suitable is a particular language for a particular task.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Furthermore, you can add programming languages to be considered for implementation and of course, you can suggest new tasks to be resolved.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
There is very little about Delphi at &lt;b&gt;RosettaCode&lt;/b&gt;. I encourage the Delphi community to fill the pending tasks for Delphi and suggest new tasks as well.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Delphi is very powerful, let’s share it with everybody.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
These are my contributions so far: &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Singleton#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Singleton&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Primality_by_trial_division#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Primality by trial division&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Unicode_variable_names#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Unicode variable names&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Date_manipulation#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Date manipulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Draw_a_sphere#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Draw a sphere&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/MD5#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;MD5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/XML/Input#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;XML/Input&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/XML/Output#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;XML/Output&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Mutual_recursion#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Mutual recursion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Soundex#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Soundex&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Delegates#Delphi&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Delegates&lt;/a&gt;&amp;nbsp; &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Finally, I want to highlight that &lt;b&gt;RosettaCode&lt;/b&gt; is about all programming languages. Resolving tasks in a single language is not enough. Don’t be shy, add the solutions in all the languages you can :-)&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/3590725687895298113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/08/contribute-to-delphi-at-rosettacode.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/3590725687895298113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/3590725687895298113'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/08/contribute-to-delphi-at-rosettacode.html' title='My contributions to the Delphi community at RosettaCode'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-7709692292996223631</id><published>2011-07-13T17:24:00.045-04:00</published><updated>2015-10-15T20:16:04.366-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Creational Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Parameterized Factory Method in Delphi</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Factory Method is a creational design pattern, whose &lt;i&gt;intent &lt;/i&gt;(according to &lt;a href=&quot;http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612&quot; height=&quot;1&quot; style=&quot;border: none !important; margin: 0px !important; padding: 0px !important;&quot; width=&quot;1&quot; /&gt;) is to:&lt;br /&gt;
&lt;br /&gt;
“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;color: blue; text-align: center;&quot;&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;Do you want to know more about design patterns? Check reference [1] at the bottom for extra reading.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
In this post we will consider a variation of the pattern referred as parameterized factory method. This variation just refers to the first part of the &lt;i&gt;intent&lt;/i&gt;, that is, “define an interface for creating an object”. Why is that?&amp;nbsp; What about the rest of the &lt;i&gt;intent&lt;/i&gt;? Well, there are times in which sub-classing is not possible or not suitable; nonetheless, it is useful to define a factory method to encapsulate the creation of an object.&lt;br /&gt;
&lt;br /&gt;
Let’s proceed with the example we used in our previous post (&lt;a href=&quot;http://www.yanniel.info/2011/06/template-method-design-pattern-delphi.html&quot;&gt;template design pattern&lt;/a&gt;); that is: &lt;i&gt;Design an application that allows drawing different styles of houses (ei. country house, city house) using ASCII art&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
The GUI of our app contains some VCL components as you can see in the images below. Clicking the buttons will result in an ASCII house printed out in the memo area. Depending on the &lt;i&gt;Draw…&lt;/i&gt; button being clicked, the house will look differently: it can be a country house or a city house.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekjeO529wgXTspg3chXeorKssHA-EDoJzEDh5g9O5irb698nwWGuRYtm0UnFUc-J_sCMBzbvtUavYGSRTUwjfPSwi7dxbZZXohUZswSL6NG5vLBNc0kUyTAbeU3SL_7dmpTNW2CmbbV-O/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Country+House.JPG&quot; imageanchor=&quot;1&quot; rel=&quot;nofollow&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Factory Pattern Example (Delphi) – Country House&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekjeO529wgXTspg3chXeorKssHA-EDoJzEDh5g9O5irb698nwWGuRYtm0UnFUc-J_sCMBzbvtUavYGSRTUwjfPSwi7dxbZZXohUZswSL6NG5vLBNc0kUyTAbeU3SL_7dmpTNW2CmbbV-O/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Country+House.JPG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Figure1&lt;/b&gt; A Country House (&lt;i&gt;Draw Country House&lt;/i&gt; button was clicked)&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1kh8W0gSYDXegrPF9CO9gVLfJi7NjPN7Lv0AlPnHbjy3cABYUkc9074xJYlhLsdoQwztOKAosFy0ty3-Xyd1GF5SfDDbRvV7wNHcFXBjHp0eSQiBy4oBJgwttkmGag8hpakUseayFMbMg/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+City+House.JPG&quot; imageanchor=&quot;1&quot; rel=&quot;nofollow&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Factory Pattern Example (Delphi) – City House&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1kh8W0gSYDXegrPF9CO9gVLfJi7NjPN7Lv0AlPnHbjy3cABYUkc9074xJYlhLsdoQwztOKAosFy0ty3-Xyd1GF5SfDDbRvV7wNHcFXBjHp0eSQiBy4oBJgwttkmGag8hpakUseayFMbMg/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+City+House.JPG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Figure 2&lt;/b&gt; A City House (&lt;i&gt;Draw City House&lt;/i&gt; button was clicked)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Behind the scenes, assume that we have implemented the following class hierarchy:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8e9-P__OlFyrhzocQoEYhjJNTq7YKLtt-r33z1rCYvACPjl9OQV0Ou1-y5FvQOqqH-nV76GzrmUgBv4XXub4c9XBeHB7si6cQ7X7OZcX75HjBRTeBXSOeXD-72H4eFR9HnmH1kub75KIn/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Class+diagram.JPG&quot; imageanchor=&quot;1&quot; rel=&quot;nofollow&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Factory Pattern Example (Delphi) – Class diagram&quot; border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8e9-P__OlFyrhzocQoEYhjJNTq7YKLtt-r33z1rCYvACPjl9OQV0Ou1-y5FvQOqqH-nV76GzrmUgBv4XXub4c9XBeHB7si6cQ7X7OZcX75HjBRTeBXSOeXD-72H4eFR9HnmH1kub75KIn/s320/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Class+diagram.JPG&quot; width=&quot;295&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;THouse&lt;/b&gt; is an abstract class that defines several methods for displaying the different parts of the house [2] or the house as a whole [3]. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;TCountryHouse&lt;/b&gt; and &lt;b&gt;TCityHouse&lt;/b&gt; are two concrete (non-abstract) classes that actually override some of the methods of its superclass, allowing this way different look-and-feel; that is, a house in the country and a house in the city look differently.&lt;br /&gt;
&lt;br /&gt;
When a button is clicked, the corresponding OnClick event is triggered. We have to provide logic (source code) to define what the button is going to do in response to the OnClick event. Using fancy words, we have to implement the event handler for the OnClick event. I have created the following event handler which is going to be shared by both buttons [4]:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
//OnClick event handler for the buttons&lt;br /&gt;
procedure TfrmMain.btnDrawGenericHouseClick(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; House: THouse;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //If the &quot;Sender&quot; object is not a button do nothing&lt;br /&gt;
&amp;nbsp; if not(Sender is TButton) then Exit;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //The concrete house object being created depends&lt;br /&gt;
&amp;nbsp; //on the button being clicked&lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;if TButton(Sender).Name = &#39;btnDrawCountryHouse&#39; then&lt;/span&gt;&lt;br style=&quot;color: blue;&quot; /&gt;&lt;span style=&quot;color: blue;&quot;&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; House:= TCountryHouse.Create&lt;/span&gt;&lt;br style=&quot;color: blue;&quot; /&gt;&lt;span style=&quot;color: blue;&quot;&gt; &amp;nbsp; else if TButton(Sender).Name = &#39;btnDrawCityHouse&#39; then&lt;/span&gt;&lt;br style=&quot;color: blue;&quot; /&gt;&lt;span style=&quot;color: blue;&quot;&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; House:= TCityHouse.Create;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; with House do&lt;br /&gt;
&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //cmbHasChimney is a combo box (TComboBox) that allows&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //to decide whether to add a chimney or not to the house&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; case cmbHasChimney.ItemIndex of&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0: HasChimney:= True;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1: HasChimney:= False;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //&quot;memFrame&quot; is a memo (TMemo) used to print out the house.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; memFrame.Text:= BuildIt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
This works of course, but it lacks flexibility. What happens if we want to add a third button, or a fourth, or a five in order to add new types of houses? In that case, you will have to rework the code above and the fragment in blue will grow up big as new house types are added. You will end coding something like this: &lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;nbsp; if TButton(Sender).Name = &#39;btnDrawCountryHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; House:= TCountryHouse.Create&lt;br /&gt;
&amp;nbsp; else if TButton(Sender).Name = &#39;btnDrawCityHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;House&lt;/code&gt;&lt;code&gt;:= TCityHouse.Create&lt;br /&gt;
else if TButton(Sender).Name = &#39;btnDrawDogHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;House&lt;/code&gt;&lt;code&gt;:= TDogHouse.Create&lt;br /&gt;
else if TButton(Sender).Name = &#39;btnDrawTreeHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;House&lt;/code&gt;&lt;code&gt;:= TTreeHouse.Create&lt;br /&gt;
else if TButton(Sender).Name = &#39;btnDrawGhostHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;House&lt;/code&gt;&lt;code&gt;:= TGhostHouse.Create;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
That is the only part changing within the method. Why don’t we take that chunk of code and place it somewhere else? For that, we can create a factory method. The factory method will take one parameter to decide the concrete house type to instantiate [4]. The return type of the factory method will be &lt;b&gt;THouse&lt;/b&gt;, because &lt;b&gt;THouse&lt;/b&gt; enfolds all the other house subtypes. What about this?&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
function TfrmMain.MakeHouse(Sender: TObject): THouse;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if TButton(Sender).Name = &#39;btnDrawCountryHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= TCountryHouse.Create&lt;br /&gt;
&amp;nbsp; else if TButton(Sender).Name = &#39;btnDrawCityHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;Result&lt;/code&gt;&lt;code&gt;:= TCityHouse.Create&lt;br /&gt;
else if TButton(Sender).Name = &#39;btnDrawDogHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;Result&lt;/code&gt;&lt;code&gt;:= TDogHouse.Create&lt;br /&gt;
else if TButton(Sender).Name = &#39;btnDrawTreeHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;Result&lt;/code&gt;&lt;code&gt;:= TTreeHouse.Create&lt;br /&gt;
else if TButton(Sender).Name = &#39;btnDrawGhostHouse&#39; then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;Result&lt;/code&gt;&lt;code&gt;:= TGhostHouse.Create;&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
MakeHouse is a parameterized factory method. It is called factory because its only purpose in life is to create an object. It is adorned with the parameterized term, because it takes a parameter (Sender) to decide the concrete class to instantiate. &lt;br /&gt;
&lt;br /&gt;
What does this mean to our previous code (event handler method)? Well, see it by yourself:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
//OnClick event handler for the buttons&lt;br /&gt;
procedure TfrmMain.btnDrawGenericHouseClick(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; House: THouse;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //If the &quot;Sender&quot; object is not a button do nothing&lt;br /&gt;
&amp;nbsp; if not(Sender is TButton) then Exit;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //The concrete house object being created depends&lt;br /&gt;
&amp;nbsp; //on the button being clicked&lt;br /&gt;
&amp;nbsp; House:= MakeHouse(Sender); //See our factory method in action&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; with House do&lt;br /&gt;
&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //cmbHasChimney is a combo box (TComboBox) that allows&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //to decide whether to add a chimney or not to the house&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; case cmbHasChimney.ItemIndex of&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0: HasChimney:= True;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1: HasChimney:= False;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //&quot;memFrame&quot; is a memo (TMemo) used to print out the house.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; memFrame.Text:= BuildIt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Now, as you can see, the event handler will remain the same no matter how many different subtypes of houses we have (add). Everything about the creation of a house object is isolated in the factory method. &lt;br /&gt;
&lt;br /&gt;
One final comment: Delphi is a hybrid programming language, allowing both structured and object oriented programming. In Delphi, we can have functions outside all classes’ scope. That’s not very Object Oriented. Isn’t? Besides, you can’t do that in languages like Java, Python, Ruby or C#.&lt;br /&gt;
&lt;br /&gt;
In general, you should have a Factory class containing the factory method. In this particular Delphi example you might argue that we are just adding code for nothing. Yes, I give you that. But there are cases, in which having a hierarchy of factory classes comes naturally and the subfactories decide the concrete object to be created. We’ll cover that scenario in future posts :-)&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&lt;u&gt;&lt;b&gt;Notes:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
[1] Books about Design Patterns:&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0596007124&amp;amp;asins=0596007124&amp;amp;linkId=PILQCWZU7WENR3F6&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;

&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0201633612&amp;amp;asins=0201633612&amp;amp;linkId=S276LENJUNFY3V7F&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;

&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0321213351&amp;amp;asins=0321213351&amp;amp;linkId=C32AUAPTKLUF5S62&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;
&lt;br /&gt;
&lt;br /&gt;
[2] &lt;b&gt;BuildFloor()&lt;/b&gt;, &lt;b&gt;BuildWalls()&lt;/b&gt;, &lt;b&gt;BuildRoof()&lt;/b&gt;, &lt;b&gt;BuildChimney()&lt;/b&gt;. These methods draw out the floor, walls, roof and chimney (if any) respectively.&lt;br /&gt;
&lt;br /&gt;
[3] &lt;b&gt;BuildIt()&lt;/b&gt;: this method calls the methods in [2] and as a result it draws the whole house.&lt;br /&gt;
&lt;br /&gt;
[4] You can define the event handler for the buttons at design time using Delphi’s Object Inspector&lt;/div&gt;
&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/7709692292996223631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/07/parameterized-factory-method-delphi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7709692292996223631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/7709692292996223631'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/07/parameterized-factory-method-delphi.html' title='Parameterized Factory Method in Delphi'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekjeO529wgXTspg3chXeorKssHA-EDoJzEDh5g9O5irb698nwWGuRYtm0UnFUc-J_sCMBzbvtUavYGSRTUwjfPSwi7dxbZZXohUZswSL6NG5vLBNc0kUyTAbeU3SL_7dmpTNW2CmbbV-O/s72-c/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Country+House.JPG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-4979874709139780437</id><published>2011-06-24T15:44:00.125-04:00</published><updated>2015-10-15T20:19:57.019-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Behavioral Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Template Method"/><title type='text'>Template Method Design Pattern in Delphi. A working example</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
The Template Method Pattern is very easy to understand and implement. Here’s the definition borrowed from &lt;a href=&quot;http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612&quot; height=&quot;1&quot; style=&quot;border: none !important; margin: 0px !important; padding: 0px !important;&quot; width=&quot;1&quot; /&gt; book:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
“Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm&#39;s structure.”&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Let’s try to understand the pattern walking through a simple example. For implementing the solution we’ll use Delphi XE, but it should work for previous versions as well.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
This is the wording of the example: &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Design an application that allows drawing different styles of houses (ei. country house, city house) using ASCII art [1].&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
In the following image there’s a prototype of the user interface.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekjeO529wgXTspg3chXeorKssHA-EDoJzEDh5g9O5irb698nwWGuRYtm0UnFUc-J_sCMBzbvtUavYGSRTUwjfPSwi7dxbZZXohUZswSL6NG5vLBNc0kUyTAbeU3SL_7dmpTNW2CmbbV-O/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Country+House.JPG&quot; imageanchor=&quot;1&quot; rel=&quot;nofollow&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Template Pattern Example (Delphi) – Country House&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekjeO529wgXTspg3chXeorKssHA-EDoJzEDh5g9O5irb698nwWGuRYtm0UnFUc-J_sCMBzbvtUavYGSRTUwjfPSwi7dxbZZXohUZswSL6NG5vLBNc0kUyTAbeU3SL_7dmpTNW2CmbbV-O/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Country+House.JPG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The GUI is composed by a form, a memo [2], two buttons, a label and a combo box. Using the combo box you can choose whether your house will have a chimney or not. Clicking the buttons will result in an ASCII house printed out in the memo area. In the example above, the Draw Country House was clicked. If you click the other button, you will get city house like the one below:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1kh8W0gSYDXegrPF9CO9gVLfJi7NjPN7Lv0AlPnHbjy3cABYUkc9074xJYlhLsdoQwztOKAosFy0ty3-Xyd1GF5SfDDbRvV7wNHcFXBjHp0eSQiBy4oBJgwttkmGag8hpakUseayFMbMg/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+City+House.JPG&quot; imageanchor=&quot;1&quot; rel=&quot;nofollow&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Template Pattern Example (Delphi) – City House&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1kh8W0gSYDXegrPF9CO9gVLfJi7NjPN7Lv0AlPnHbjy3cABYUkc9074xJYlhLsdoQwztOKAosFy0ty3-Xyd1GF5SfDDbRvV7wNHcFXBjHp0eSQiBy4oBJgwttkmGag8hpakUseayFMbMg/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+City+House.JPG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
What happens if you select “No” in the combo box? Try it and let me know :-) &lt;a href=&quot;http://sites.google.com/site/yanniel821024/TemplateMethod_Demo.zip&quot; rel=&quot;nofollow&quot;&gt;Here’s the link to the EXE&lt;/a&gt;. This EXE is harmless; I am not a bad guy: no Trojans, no viruses, just Delphi :-) &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Now, what classes do we need to make this work? Take a look at the following class diagram and try to make sense of it:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8e9-P__OlFyrhzocQoEYhjJNTq7YKLtt-r33z1rCYvACPjl9OQV0Ou1-y5FvQOqqH-nV76GzrmUgBv4XXub4c9XBeHB7si6cQ7X7OZcX75HjBRTeBXSOeXD-72H4eFR9HnmH1kub75KIn/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Class+diagram.JPG&quot; imageanchor=&quot;1&quot; rel=&quot;nofollow&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Template Pattern Example (Delphi) – Class diagram&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8e9-P__OlFyrhzocQoEYhjJNTq7YKLtt-r33z1rCYvACPjl9OQV0Ou1-y5FvQOqqH-nV76GzrmUgBv4XXub4c9XBeHB7si6cQ7X7OZcX75HjBRTeBXSOeXD-72H4eFR9HnmH1kub75KIn/s1600/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Class+diagram.JPG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
We have an abstract superclass &lt;b&gt;THouse&lt;/b&gt;, which contains four abstract (pure virtual) methods: &lt;b&gt;BuildFloor&lt;/b&gt;, &lt;b&gt;BuildWalls&lt;/b&gt;, &lt;b&gt;BuildRoof &lt;/b&gt;and &lt;b&gt;BuildChimney&lt;/b&gt;. These methods are implemented in the descending classes &lt;b&gt;TCountryHouse &lt;/b&gt;and &lt;b&gt;TCityHouse&lt;/b&gt;. Pay special attention to the method &lt;b&gt;BuildIt &lt;/b&gt;in &lt;b&gt;THouse&lt;/b&gt;. This method is an instance method that is inherited by both concrete subclasses: &lt;b&gt;TCountryHouse &lt;/b&gt;and &lt;b&gt;TCityHouse&lt;/b&gt;.&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I want to be more detailed: &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The &lt;b&gt;BuildIt &lt;/b&gt;method is implemented just once in the class &lt;b&gt;THouse&lt;/b&gt;. The subclasses &lt;b&gt;TCountryHouse &lt;/b&gt;and &lt;b&gt;TCityHouse &lt;/b&gt;don’t have to implement the &lt;b&gt;BuildIt &lt;/b&gt;method. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
The &lt;b&gt;BuildFloor&lt;/b&gt;, &lt;b&gt;BuildWalls&lt;/b&gt;, &lt;b&gt;BuildRoof &lt;/b&gt;and &lt;b&gt;BuildChimney &lt;/b&gt;methods have no implementation under the &lt;b&gt;THouse &lt;/b&gt;class. The &lt;b&gt;TCountryHouse &lt;/b&gt;has one implementation of these methods, while &lt;b&gt;TCityHouse &lt;/b&gt;have a different implementation of them.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
This is how the &lt;b&gt;BuildIt &lt;/b&gt;method looks like:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;function THouse.BuildIt: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; Result:= BuildRoof&amp;nbsp; +&amp;nbsp; //Step 1&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BuildWalls +&amp;nbsp; //Step 2&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BuildFloor;&amp;nbsp;&amp;nbsp; //Step 3&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; if FHasChimney then&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= BuildChimney+ Result;&amp;nbsp; //Step 4 (conditional)&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
This method defines a general algorithm to build a house…it doesn’t take into consideration the kind of house that’s been built. Notice that the steps for building the roof, walls, floor and chimney (if any) have been deferred to the subclasses. The &lt;b&gt;BuildIt&lt;/b&gt; method is known as a template method that gives the name to this pattern.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Let me give you an idea of the implementation of the &lt;b&gt;BuildFloor&lt;/b&gt; method. This method is implemented directly by the subclasses. Take a look:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
&lt;code&gt;function TCountryHouse.BuildFloor: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; Result:=&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; &#39;~~~~~&quot;&amp;nbsp;&amp;nbsp; &quot;~~~~~~~~~~~~~~~~~~~~~~~~&amp;nbsp; &#39;;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;function TCityHouse.BuildFloor: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; Result:=&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; &#39;******************____****************&#39;#13#10 +&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;&amp;nbsp; &#39;**************************************&#39;;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Notice that the implementation of the &lt;b&gt;BuildFloor&lt;/b&gt; method is different in both subclasses &lt;b&gt;TCountryHouse&lt;/b&gt; and &lt;b&gt;TCityHouse&lt;/b&gt;. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
For the implementation of the remaining methods refer to reference [5]. For the full source code refer to [3]. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
In conclusion, the template method pattern needs an abstract superclass to implement a template method (common for all subclasses). The steps within this template method are deferred into methods that are implemented by the concrete subclasses. Did you get it? :-)&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Do you want to know more about design patterns? The books in reference [4] are just what you need. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;u&gt;&lt;b&gt;References:&lt;/b&gt;&lt;/u&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
[1] I am borrowing the ASCII designs from &lt;a href=&quot;http://www.ascii-fr.com/-House-.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Asciiworld.com : House&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
[2] Make sure to use a fixed-width font (Courier, Monaco, Courier New, Lucida Console, etc.) for the memo, otherwise the drawing will look fuzzy.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
[3] Get the full source code of this example &lt;a href=&quot;http://sites.google.com/site/yanniel821024/DesignPatternsinDelphi%5BFactoryMethod-TemplateMethod%5D.rar&quot; rel=&quot;nofollow&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
[4] Books on Design Patterns:&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0596007124&amp;amp;asins=0596007124&amp;amp;linkId=PILQCWZU7WENR3F6&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;

&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0201633612&amp;amp;asins=0201633612&amp;amp;linkId=S276LENJUNFY3V7F&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;

&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;amp;OneJS=1&amp;amp;Operation=GetAdHtml&amp;amp;MarketPlace=US&amp;amp;source=ac&amp;amp;ref=tf_til&amp;amp;ad_type=product_link&amp;amp;tracking_id=lmaoookaiie-20&amp;amp;marketplace=amazon&amp;amp;region=US&amp;amp;placement=0321213351&amp;amp;asins=0321213351&amp;amp;linkId=C32AUAPTKLUF5S62&amp;amp;show_border=true&amp;amp;link_opens_in_new_window=true&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;
&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[5] The full source code of the unit:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;unit TemplatePatternExample;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; THouse = class&lt;br /&gt;
&amp;nbsp; private&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; FHasChimney: Boolean;&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; property HasChimney: Boolean read&amp;nbsp; FHasChimney&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; write FHasChimney;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildFloor: string;&amp;nbsp;&amp;nbsp; virtual; abstract;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildWalls: string;&amp;nbsp;&amp;nbsp; virtual; abstract;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildRoof: string;&amp;nbsp;&amp;nbsp;&amp;nbsp; virtual; abstract;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildChimney: string; virtual; abstract;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildIt: string;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; TCountryHouse = class(THouse)&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildFloor: string;&amp;nbsp;&amp;nbsp; override;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildWalls: string;&amp;nbsp;&amp;nbsp; override;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildRoof: string;&amp;nbsp;&amp;nbsp;&amp;nbsp; override;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildChimney: string; override;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; TCityHouse = class(THouse)&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildFloor: string;&amp;nbsp;&amp;nbsp; override;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildWalls: string;&amp;nbsp;&amp;nbsp; override;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildRoof: string;&amp;nbsp;&amp;nbsp;&amp;nbsp; override;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function BuildChimney: string; override;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ THouse }&lt;br /&gt;
&lt;br /&gt;
constructor THouse.Create;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; inherited Create;&lt;br /&gt;
&amp;nbsp; FHasChimney:= True;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function THouse.BuildIt: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= BuildRoof&amp;nbsp; +&amp;nbsp; //Step 1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BuildWalls +&amp;nbsp; //Step 2&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BuildFloor;&amp;nbsp;&amp;nbsp; //Step 3&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if FHasChimney then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= BuildChimney+ Result;&amp;nbsp; //Step 4 (conditional)&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{ TCountryHouse }&lt;br /&gt;
&lt;br /&gt;
function TCountryHouse.BuildChimney: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:=&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&amp;nbsp;&amp;nbsp; )&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&amp;nbsp;&amp;nbsp;&amp;nbsp; )&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&amp;nbsp;&amp;nbsp;&amp;nbsp; )&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&amp;nbsp;&amp;nbsp;&amp;nbsp; )&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&amp;nbsp; )&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&amp;nbsp; (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (_)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ ]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCountryHouse.BuildRoof: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:=&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ___________________&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /\&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ______&amp;nbsp;&amp;nbsp;&amp;nbsp; \&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //_\&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \&amp;nbsp;&amp;nbsp;&amp;nbsp; /\&amp;nbsp;&amp;nbsp;&amp;nbsp; \&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; //___\&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \__/&amp;nbsp; \&amp;nbsp;&amp;nbsp;&amp;nbsp; \&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp; //_____\&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \ |[]|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; //_______\&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \|__|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39; /XXXXXXXXXX\&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \ &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;/_I_II&amp;nbsp; I__I_\__________________\&#39;#13#10;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCountryHouse.BuildWalls: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:=&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; I_I|&amp;nbsp; I__I_____[]_|_[]_____I&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; I_II&amp;nbsp; I__I_____[]_|_[]_____I&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; I II__I&amp;nbsp; I&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XXXXXXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; I&#39;#13#10;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCountryHouse.BuildFloor: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:=&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &#39;~~~~~&quot;&amp;nbsp;&amp;nbsp; &quot;~~~~~~~~~~~~~~~~~~~~~~~~&amp;nbsp; &#39;;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{ TCityHouse }&lt;br /&gt;
&lt;br /&gt;
function TCityHouse.BuildChimney: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:=&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ====&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; !!!!&amp;nbsp; &#39;#13#10;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCityHouse.BuildRoof: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:=&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ==========================&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp;&amp;nbsp;&amp;nbsp; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&amp;nbsp; &#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&#39;#13#10;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCityHouse.BuildWalls: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:=&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _____&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _____&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | | |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | | |&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |-|-|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |-|-|&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #####&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #####&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _____&amp;nbsp;&amp;nbsp; ____&amp;nbsp;&amp;nbsp; _____&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | | |&amp;nbsp;&amp;nbsp; @@@@&amp;nbsp;&amp;nbsp; | | |&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |-|-|&amp;nbsp;&amp;nbsp; @@@@&amp;nbsp;&amp;nbsp; |-|-|&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #####&amp;nbsp;&amp;nbsp; @@*@&amp;nbsp;&amp;nbsp; #####&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;&amp;nbsp; ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @@@@&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ||&#39;#13#10;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCityHouse.BuildFloor: string;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:=&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &#39;******************____****************&#39;#13#10 +&lt;br /&gt;
&amp;nbsp; &#39;**************************************&#39;;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;/code&gt;&lt;a href=&quot;http://www.yanniel.info/p/delphi-programming.html&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/4979874709139780437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/06/template-method-design-pattern-delphi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4979874709139780437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/4979874709139780437'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/06/template-method-design-pattern-delphi.html' title='Template Method Design Pattern in Delphi. A working example'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekjeO529wgXTspg3chXeorKssHA-EDoJzEDh5g9O5irb698nwWGuRYtm0UnFUc-J_sCMBzbvtUavYGSRTUwjfPSwi7dxbZZXohUZswSL6NG5vLBNc0kUyTAbeU3SL_7dmpTNW2CmbbV-O/s72-c/Template+Pattern+Example+%2528Delphi%2529+%25E2%2580%2593+Country+House.JPG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3701737190756431503.post-8524807676052350250</id><published>2011-06-22T21:04:00.012-04:00</published><updated>2012-12-17T20:12:14.610-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Pascal"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>New certifications available for Delphi Developers</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;
Last June 12th, 2011, I received an Embarcadero Community Newsletter pointing out that “certification exams are now available for Delphi developers.&amp;nbsp; Embarcadero&#39;s Delphi Certification Program offers two levels: &lt;a href=&quot;http://www.embarcadero.com/certification/delphi-developer&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Delphi Certified Developer&lt;/a&gt; and &lt;a href=&quot;http://www.embarcadero.com/certification/delphi-master&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Delphi Certified Master Developer&lt;/a&gt;. “&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I just passed the Delphi Developer Certification exam and thus I became a Certified Delphi Developer.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxw4B-bCBEbUnuWY2DMJm55dHRGrhT39JPQ6G7DerdU3ty_1xKZVSgyNne3EhUw2-go10NATZNiULjJqzzRBBN0Ur7rIXasrjpyvlZqikeM-i7Croqsh_-Ku30yp0HZ7nCf2tXE005Qw61/s1600/Delphi_Certified_Developer_Logo_transBkgrd.png&quot; imageanchor=&quot;1&quot; rel=&quot;nofollow&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Certified Delphi Developer&quot; border=&quot;0&quot; height=&quot;311&quot; rel=&quot;nofollow&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxw4B-bCBEbUnuWY2DMJm55dHRGrhT39JPQ6G7DerdU3ty_1xKZVSgyNne3EhUw2-go10NATZNiULjJqzzRBBN0Ur7rIXasrjpyvlZqikeM-i7Croqsh_-Ku30yp0HZ7nCf2tXE005Qw61/s320/Delphi_Certified_Developer_Logo_transBkgrd.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&amp;nbsp;Now, I want you to become certified as well :-) So, mind this:&amp;nbsp; &lt;/div&gt;
&lt;ul style=&quot;text-align: justify;&quot;&gt;
&lt;li&gt;This exam is conducted over the Internet without supervision. That means you can take the exam at home (or wherever you prefer) at your own pace. You don’t need to go to a particular place to take the exam: you just need an Internet connection and that’s pretty much it.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;The exam is cheap. It only costs $49USD.Consider for example that the prices for .NET or Java certifications are much higher.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;You can pay for the exam code online (you need an exam code to take the certification exam). Theoretically, you can pay it using VISA, MasterCard and Paypal. Warning: I tried with my VISA and Master Card cards and it didn’t work. It seems that there is (was) something wrong with the payment system. At the end, I managed to perform the payment through Paypal.&lt;/li&gt;
&lt;li&gt;The exam contains 60 questions to be answered in 60 minutes. The time is plenty; so, don’t worry about it. &lt;/li&gt;
&lt;li&gt;Be careful with the syntax questions: even if you are an experienced Delphi programmer, I would advise you to review the syntactical elements of the language before taking the test. Most times our memory becomes dusty after too much time relaying on the code completion features of the IDE. &lt;/li&gt;
&lt;li&gt;Take a look at the &lt;a href=&quot;http://www.embarcadero.com/images/dm/technical-papers/delphi-developer-certification-study-guide.pdf&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Delphi Developer Certification Study Guide&lt;/a&gt;. Make sure you cover all the topics targeted for the exam. Remember: all topics go under examination.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I wanted to take the Delphi Master Developer Certification exam as well, but guess what? - This exam is supervised and I would need to travel to USA to take it. I think I will wait until it becomes available (hopefully) in Canada.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
I belief the introduction of these certification programs is proof that Embarcadero is willing to gain a good portion of the programming market. By taking the exams you become part of the effort of bringing Delphi to the arena once more…I believe it’s worthy.&lt;br /&gt;
&lt;br /&gt;
I recently found this Delphi Certification Webinar video by Andreano Lanusse.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/bJepSwdDctQ&quot; width=&quot;420&quot;&gt;&lt;/iframe&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.yanniel.info/feeds/8524807676052350250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.yanniel.info/2011/06/certification-delphi-developers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8524807676052350250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3701737190756431503/posts/default/8524807676052350250'/><link rel='alternate' type='text/html' href='http://www.yanniel.info/2011/06/certification-delphi-developers.html' title='New certifications available for Delphi Developers'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxw4B-bCBEbUnuWY2DMJm55dHRGrhT39JPQ6G7DerdU3ty_1xKZVSgyNne3EhUw2-go10NATZNiULjJqzzRBBN0Ur7rIXasrjpyvlZqikeM-i7Croqsh_-Ku30yp0HZ7nCf2tXE005Qw61/s72-c/Delphi_Certified_Developer_Logo_transBkgrd.png" height="72" width="72"/><thr:total>0</thr:total></entry></feed>