<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lotushints &#187; Best practices</title>
	<atom:link href="http://www.lotushints.com/category/best-practices/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lotushints.com</link>
	<description>Lotus Notes tips &#38; tricks you always hoped you will not need</description>
	<lastBuildDate>Thu, 29 Dec 2011 09:47:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Demo</title>
		<link>http://www.lotushints.com/2011/01/demo/</link>
		<comments>http://www.lotushints.com/2011/01/demo/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 06:00:24 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[demo]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=541</guid>
		<description><![CDATA[A few days hence, I had an interesting debate with one of my best friends about data used in a demo. He is convinced that real user data (e.g. Name, Surname, email etc.) should be used even in a demo. I, on the other hand, am impervious to weather you use fake, real-enough or real [...]]]></description>
			<content:encoded><![CDATA[<p>A few days hence, I had an interesting debate with one of my best friends about data used in a demo. He is convinced that real user data (e.g. Name, Surname, email etc.) should be used even in a demo. I, on the other hand, am impervious to weather you use fake, real-enough or real data. As long as it is visible that e.g. email is an email.<br />
<span id="more-541"></span><br />
To better present what we were discussing, I present you with the data available:</p>
<pre>
Firstname: Web
Lastname: User
Username: user
Email: wuser@yourdomain.com
</pre>
<p>This is what he believes is good data:</p>
<pre>
Firstname: John
Lastname: Smith
Username: jsmith
Email: jsmith@gmail.com
</pre>
<p>I don&#8217;t claim that I am correct, but I find it difficult to believe that any user will have issues interpreting first set of data just as well as the other. To be perfectly honest, if I would go with the change of first name, last name and user name, I would definitely not go with the Gmail account in an e-mail address. Why? I don&#8217;t want to sound condescending, but if a user is as simple as to not being able to interpret first set of data, how on earth are you going to convince him that Gmail account will not be created for him?</p>
<p>Now, I can understand that while real data look nice, I disagree with the fact that it makes things clearer. To remind you, this is a presentation you are going to give to your end customer. The last thing you want is them to get stuck with data and not see the functionality of the application. It even might look to the customer that this is real data you are messing with. Hence, I believe that both data are correct and that it is not worth spending time to fix it.</p>
<p>In the end, it proved to be a useless discussion and the only result will be a happy face of a mobile services provider that will have the honour to bill us for the discussion.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2011/01/demo/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Android development issue no. 1</title>
		<link>http://www.lotushints.com/2010/12/android-development-issue-no-1/</link>
		<comments>http://www.lotushints.com/2010/12/android-development-issue-no-1/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 06:00:09 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[ADT]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Subclipse]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=537</guid>
		<description><![CDATA[Due to personal interest, I installed Android SDK and emulator on my machine. Now, since I am a programmer, I am most interested in actually developing applications for Android. Hence, I installed Eclipse ADT plug-in. I created a sample project, and went to edit resources. I failed miserably. I couldn&#8217;t type in the window, couldn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Due to personal interest, I installed Android SDK and emulator on my machine. Now, since I am a programmer, I am most interested in actually developing applications for Android. Hence, I installed Eclipse ADT plug-in.<br />
<span id="more-537"></span><br />
I created a sample project, and went to edit resources. I failed miserably. I couldn&#8217;t type in the window, couldn&#8217;t edit and couldn&#8217;t save a resource. Since I use Eclipse for other things as well, I have other plug-ins installed as well, e.g. Subclipse and EclipseMercurial.</p>
<p>This is where you are going to shoot yourself in the foot. Much like I have unfortunately. ADT and Subclipse apparently don&#8217;t mix. If you want to have Subclipse for other projects, you are left with no other option but to install another eclipse instance for Android development.</p>
<p>I did that and experience no problems whatsoever afterwards.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2010/12/android-development-issue-no-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Javascript string traversing</title>
		<link>http://www.lotushints.com/2010/06/javascript-string-traversing/</link>
		<comments>http://www.lotushints.com/2010/06/javascript-string-traversing/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 06:00:07 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[string traversing]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=507</guid>
		<description><![CDATA[Lately I needed to parse format that Cisco uses for specifying transfer masks and route patterns to an array of telephone numbers a user could choose from. I wrote a neat javascript function that traverses the string and does what needed. I even wrote a neat recursive function that displayed the numbers in HTML select [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I needed to parse format that Cisco uses for specifying transfer masks and route patterns to an array of telephone numbers a user could choose from. I wrote a neat javascript function that traverses the string and does what needed. I even wrote a neat recursive function that displayed the numbers in HTML select field.<br />
<span id="more-507"></span><br />
All worked fine. Until someone decided to test the thing on VM running Windows XP SP3 with IE 8.0.6001.18702 . The thing crashed. Not only that, it also displayed a nice little pop-up claiming that Javascript is running slow. We all know that really means you have an infinite loop somewhere in JS code. Thing is, I ran the code numerous times on my PC, which runs Windows XP SP3 and IE 8.0.6001.18702 as well. The only difference that my PC is not  a virtual machine. And it worked without a glitch. So I tested it to death in VMs IE and eventually located the problem.</p>
<p>Remember how you traversed a string in C? Typically you wrote something like this (and yes, I know I probably should have used a pointer):</p>
<pre>
char pszString[100] = "My silly string\0";
for (int i=0; i&lt;strlen(pszString); i++) {
   char ch = pszString[i];
   //do something spiffy
}
</pre>
<p>As far as I remember, I use that all the time in JavaScript as well. I never had any issues. Guess what? In IE on VM that was the cause of my problems. So, all I had to do was:</p>
<pre>
var pszString = new String("My silly string");
for (int i=0; i&lt;strlen(pszString); i++) {
   char ch = pszString.substr(i, 1);
   //do something spiffy
}
</pre>
<p>And the stuff magically started to work.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2010/06/javascript-string-traversing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reinventing the wheel vs. code reuse</title>
		<link>http://www.lotushints.com/2010/05/reinventing-the-wheel-vs-code-reuse/</link>
		<comments>http://www.lotushints.com/2010/05/reinventing-the-wheel-vs-code-reuse/#comments</comments>
		<pubDate>Wed, 12 May 2010 07:00:30 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[code reuse]]></category>
		<category><![CDATA[reinventing the wheel]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=501</guid>
		<description><![CDATA[Lately I have been marked as a &#8216;reinventing the wheel&#8217; guy. I don&#8217;t object to that. After all, when I see this cool new feature, I just need to see how it was made. And since I am there, I can also test my skills and rewrite it. But is it really that bad to [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I have been marked as a &#8216;reinventing the wheel&#8217; guy. I don&#8217;t object to that. After all, when I see this cool new feature, I just need to see how it was made. And since I am there, I can also test my skills and rewrite it. But is it really that bad to reinvent the wheel?</p>
<p><span id="more-501"></span></p>
<p><strong>Time spent<br />
</strong></p>
<p>One of the biggest arguments people use to justify code reuse is that it is done in a blink of an eye. Well, it is. You can just copy and paste the code or include a dynamic link library and you are done. Right? Wrong. Code reuse costs you a lot of time. You may not know it as development time, but as a learning curve. That is the time you will need to successfully implement 3rd party code into your application. So much for zero time spent. In the end it is up to you to weigh weather time spent rewriting the code will be shorter than time that you will use to learn how to implement the code. Be smart though. It makes absolutely no sense writing your own jQuery framework when you can get one in no time, however if you are thinking of doing an image pop-up, it is time to sit down and re-think the situation.</p>
<p><strong>Less bugs</strong></p>
<p>Another thing I heard a lot is that code reuse means there will be less bugs in your code. I can see how an amateur observer could see it that way. There is this code and it is bug-free code. Wrong again. Specially open source code (although vendor one is no exception) is known to not deal well with fixing bugs. Meaning, you can get a 3rd party code, implement it and then spend another 2 weeks tweaking what should be already working code. Thing is, I am yet to see bug-free software. Another thing. Someone else&#8217;s code you include into your own code, becomes your code at that moment. So think long and hard about what you will implement. After all, you might notice that your program fails as a vendor driver changes working directory each time it calls a function. This is real example btw, and I would like to see you make a smooth save from that one.</p>
<p><strong>No need to know how everything is done</strong></p>
<p>Fine. You maintain my code then. Impossible? Nah, just time consuming. Despite what everyone else might think, you need to know what you put in your code. Either you gain that knowledge by reading an implementation manual or by looking at the code directly is up to you. But at some point in future, a manager will locate you and ask a darn annoying question relating to that special 3rd party code you implemented and &#8220;um, that code is not mine&#8221; will hardly be an acceptable answer.</p>
<p>It might look like I don&#8217;t like to reuse code. That is not true. I simply refuse to implement something in my project for sheer factor that it has already been done. Thus, I usually weigh what is the fastest way to do things and then decide weather I will rewrite it or just implement something that someone else wrote. In the end, it is up to you. You are the one responsible for delivering your projects on time and for future maintenance of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2010/05/reinventing-the-wheel-vs-code-reuse/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cleaning behind you</title>
		<link>http://www.lotushints.com/2010/04/cleaning-behind-you/</link>
		<comments>http://www.lotushints.com/2010/04/cleaning-behind-you/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 06:00:03 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Code optimization]]></category>
		<category><![CDATA[custom classes]]></category>
		<category><![CDATA[delete]]></category>
		<category><![CDATA[destructor]]></category>
		<category><![CDATA[erase]]></category>
		<category><![CDATA[garbage collector]]></category>
		<category><![CDATA[memory leak]]></category>
		<category><![CDATA[Web services]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=494</guid>
		<description><![CDATA[Ending up a big project, I was brimming with confidence. The code was well structured, it ran fast despite using external web services and on top of that, it worked on test system. Oh boy, did it work. I should have seen a warning sign there. But no. I let my vanity kick  in and [...]]]></description>
			<content:encoded><![CDATA[<p>Ending up a big project, I was brimming with confidence. The code was well structured, it ran fast despite using external web services and on top of that, it worked on test system. Oh boy, did it work. I should have seen a warning sign there. But no. I let my vanity kick  in and enjoyed the good times. Yes, everything worked. Until&#8230;</p>
<p><span id="more-494"></span></p>
<p>&#8230;server crashed. With access violation problem. I feverishly scrolled through code, looking for an obvious error, but was unable to locate one at first glance. And than, slowly it dawned on me. I let garbage collection do my own dirty work. Unfortunately garbage collection in LotusScript has a small &#8220;feature&#8221;. It does not collect and disposes of web service consumers.</p>
<p>This is what my problem was. I created an abstract class that took care of initialization (including service consumer object). Then each data type had it&#8217;s own class that inherited from that abstract class. Needless to say that I forgot to add destructor that would clear web service consumer object. So, now, I had n web service consumer objects pointing to the same web service consumer, resulting in a memory leak of a size of an elephant after a huge meal and consequently a server crash.</p>
<p>But enough about me. Cleaning behind you in your code is a good practice. Not only it will make your code run smoother and look more spiffy, but it will also save you from feverish last minute code scrambling, busting your head and yelling like a mad man with a look of a rabid squirrel. So, let&#8217;s look what you can do.</p>
<p>1. <strong>Use destructors that actually do something useful in your classes.</strong></p>
<p>Having an empty Sub Delete (or none at all) is just not enough. Try  clearing your member variables as well. Specially if they are your  custom classes, web services, arrays or lists.<strong></strong></p>
<p><strong>2. Don&#8217;t be afraid to use Erase statement to clear arrays and lists you don&#8217;t need.<br />
</strong></p>
<p>Arrays and lists can take up a lot of your servers memory. Specially if you do an array of Notes objects. Be sure to clear them as soon as they are not needed anymore.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2010/04/cleaning-behind-you/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web services and arrays in LotusScript</title>
		<link>http://www.lotushints.com/2010/03/web-services-and-arrays-in-lotusscript/</link>
		<comments>http://www.lotushints.com/2010/03/web-services-and-arrays-in-lotusscript/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 06:00:16 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Web services]]></category>
		<category><![CDATA[LotusScript]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=490</guid>
		<description><![CDATA[Recently, I was working on an agent that used a web service to export data. Now, I don&#8217;t know if you noticed, but for some reason, consuming services is way easier in LotusScript than it is in Java. As far as I know, and I could be wrong, you need to import Axis in Java [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I was working on an agent that used a web service to export data. Now, I don&#8217;t know if you noticed, but for some reason, consuming services is way easier in LotusScript than it is in Java. As far as I know, and I could be wrong, you need to import Axis in Java to do anything with a Web service consumer.</p>
<p><span id="more-490"></span></p>
<p>In LotusScript, consuming web services is plain easy. You just import the WSDL, which can be located either on your file system or directly on the web and you are good to go.</p>
<p>Sounds too good to be true? It is. There are couple of limitations, that will make you swear like a gypsy on a bad day.</p>
<ol>
<li>Variables and function names must not be longer than 46 characters.</li>
<li>There is no way in hell your code will know how to process an array, that was passed as a result.</li>
</ol>
<p>Don&#8217;t get me wrong. This is most certainly not a problem when Web service itself is pretty simple. However, it becomes an annoyance when you start using complex 3rd party Web services.</p>
<p><strong>How to get around those?</strong></p>
<p>For 3rd party services, I guess it depends from case to case. For one web service, we actually had to come up with adapter web service written in C#, that would translate interfaces needed to something that could be used in LotusScript. I guess we could have used Java, but that caused some memory leaks.</p>
<p>If you are doing your own service, just make sure, that you don&#8217;t return any arrays and that your variables are according to the consensus of LotusScript and youa re good to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2010/03/web-services-and-arrays-in-lotusscript/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Software that makes you go arrrrrrgh</title>
		<link>http://www.lotushints.com/2010/02/software-that-makes-you-go-arrrrrrgh/</link>
		<comments>http://www.lotushints.com/2010/02/software-that-makes-you-go-arrrrrrgh/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 06:00:51 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=486</guid>
		<description><![CDATA[Recently, I had a &#8220;privilege&#8221; to acquaint myself with numerous small business applications for Windows. First, I would like to state that there is some good software out there and kudos to all of you who deliver it. Unfortunately, such software is in wast minority. However, you can quickly detect such software. Installation process is [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I had a &#8220;privilege&#8221; to acquaint myself with numerous small business applications for Windows. First, I would like to state that there is some good software out there and kudos to all of you who deliver it. Unfortunately, such software is in wast minority. However, you can quickly detect such software. Installation process is full of unreasonable demands, requests and limitations.</p>
<p><span id="more-486"></span></p>
<p><strong>Thou shall not change the name of the database</strong></p>
<p>Seriously. Why not? Don&#8217;t get me wrong. Once the program is installed, this is certainly not needed. But, during install process, I should be able to make a choice of the database name. Why? Well, perhaps I don&#8217;t like the default name. Perhaps I find it confusing. Perhaps, I even have to follow some sort of pseudo naming standard. But no. Instead, there is a nice guy on the other side of a phone line elaborating how this would be impossible. Right.</p>
<p><strong>Your computer name shall be this and that</strong></p>
<p>This one popped the top. In one installation guide I actually found this sentence: &#8220;Your computer name must not contain dash character&#8221;. Now, for the life of me, I cannot imagine why someone would be so bold as to ask me that. No, actually, I do. I bet their database is in following format <em>&lt;name of your pc&gt;-&lt;some db name&gt;-&lt;year or whatever&gt;</em> and they are having issues parsing out database name and whatever is left afterward. This or some other idiotic reason.</p>
<p>It is even more annoying as being a developer I know for sure, they could have just parsed dashes out of your computer name for their application use only. But for some reason, they just thought it was smart to ask the customer to do it instead.</p>
<p><strong>This is a server, but we don&#8217;t support any Windows Server editions</strong></p>
<p>Another funny thing. This happened rarely, as some were bright enough not put OS specification in their guides. Still some applications claimed that they are servers, but can only run on or only support Windows XP or Vista. I know that most small businesses don&#8217;t have plenty of Windows Servers, but I am sure some do. And it would really take about 1 hour of install time + install time of application + 30 minutes to support Windows Server as well.</p>
<p><strong>Making user make a choice, even though the setting should not be altered<br />
</strong></p>
<p>This only shows how much time did a software company took to create an installer. Imagine this. One application was so bold, to display to user several types of application he wants to install. Next screen was install location. For type 1, installation guide claims: &#8220;If this type is selected, leave install location as is, or application will not work.&#8221;</p>
<p>Why would you give a user a chance to change installation location for type 1, if he is not allowed to change it? I am certainly the first person that would install application to Program Files folder. First, that folder is there for reason of storing installed programs. Second, I want the option to select any install directory. Perhaps I am low on space on C disk?</p>
<p>Still, application would not work, making me to reinstall the damn thing all over again. There goes another 30 minutes.</p>
<p><strong>Forcing users to do pre- and post-install tasks</strong></p>
<p>If you have seen any Microsoft installer, you know that the installer itself takes care of all prerequisites and post install operations. Unfortunately, some think that it is better to torture their customers by forcing them to first install prerequisites (these are all on the CD with application) and then run setup. And if this wasn&#8217;t bad enough, hey, you have to wait for data to initialize upon first start, which is usually a time consuming thing. And installers in most cases don&#8217;t even check for prerequisites for install. So, you just might end up installing software and then banging your head as to why it doesn&#8217;t work.</p>
<p>And another thing. I am a person that will automatically search setup.exe or something.msi on the CD. And I think I am not alone there. There is a 100% probability that I will not click on dxyz_fmlctw.exe, which is a self extracting ZIP file at that.</p>
<p><strong>Covering up laziness with stupid statements</strong></p>
<p>This is not only tied to small business applications. Raise your hand if you have seen this or similar type of statement: &#8220;After installation, you might need to restart your computer&#8221;. Shouldn&#8217;t developers know if computer restart is necessary or not? This just looks like they don&#8217;t know. You probably will have to restart. It is just that they were too lazy to check if that is true.</p>
<p><strong>Forcing Administrator access rights to run the application</strong></p>
<p>And this beauty ends it all. Some applications just would not run without a user being granted at least Local Administrator access. No comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2010/02/software-that-makes-you-go-arrrrrrgh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What not to do in multi-domain evnironment</title>
		<link>http://www.lotushints.com/2009/09/what-not-to-do-in-multi-domain-evnironment/</link>
		<comments>http://www.lotushints.com/2009/09/what-not-to-do-in-multi-domain-evnironment/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 07:00:25 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Lotus Domino]]></category>
		<category><![CDATA[Sametime]]></category>
		<category><![CDATA[names.nsf]]></category>
		<category><![CDATA[user id]]></category>
		<category><![CDATA[username]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=432</guid>
		<description><![CDATA[There is one thing you oughtn&#8217;t do in multi-domain environment. Ever. We did it, as it was needed to successfully connect Cisco Click-to-call plug-in for Sametime with Cisco Presence server. What is it? Don&#8217;t change UserId in names.nsf database. OK. So I am not entirely truthful. You can do that, but make sure you add [...]]]></description>
			<content:encoded><![CDATA[<p>There is one thing you oughtn&#8217;t do in multi-domain environment. Ever. We did it, as it was needed to successfully connect Cisco Click-to-call plug-in for Sametime with Cisco Presence server.</p>
<p><span id="more-432"></span></p>
<h3><strong>What is it? </strong></h3>
<p>Don&#8217;t change UserId in names.nsf database. OK. So I am not entirely truthful. You can do that, but make sure you add previous UserId to Username field.  But if you don&#8217;t, in best case, you can expect angry calls from your users, as e-mails from alternative domains will not be delivered to them. That&#8217;s your best case. Worst case is, no one will know and you will lose customers. Lucky for us, we had best case scenario.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/09/what-not-to-do-in-multi-domain-evnironment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Absolute positioned objects hiding behind flash animation</title>
		<link>http://www.lotushints.com/2009/07/absolute-positioned-objects-hiding-behind-flash-animation/</link>
		<comments>http://www.lotushints.com/2009/07/absolute-positioned-objects-hiding-behind-flash-animation/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 06:00:45 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[absolute]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[HTML]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=383</guid>
		<description><![CDATA[Anyone dealing with HTML will or already has encountered an interesting behavior of embedded objects and absolute positioned objects. When embedded object (e.g. flash animation) is positioned over part or entire absolute positioned object, absolute position object is always displayed behind embedded one. What to do? A first thing that I always thought of was [...]]]></description>
			<content:encoded><![CDATA[<p>Anyone dealing with HTML will or already has encountered an interesting behavior of embedded objects and absolute positioned objects. When embedded object (e.g. flash animation) is positioned over part or entire absolute positioned object, absolute position object is always displayed behind embedded one.</p>
<p><span id="more-383"></span></p>
<p><strong>What to do?</strong></p>
<p>A first thing that I always thought of was z-indexes. Only one problem there. Z-index doesn&#8217;t work  in Internet Explorer in this case. But how can it be solved?</p>
<p>There is an attribute you can set for embedded objects called <em>wmode</em>. If this attribute contains value of <em>transparent</em>, you will force embedded object to display behind the absolute positioned one.</p>
<p>Example:
<pre>
&lt;embed width="465" height="285"
type="application/x-shockwave-flash" src="myflashanimation.swf"
style="" name="movie_player" quality="high"
allowfullscreen="true" allowscriptaccess="always" flashvars=""
<strong>wmode="transparent"</strong> id="movie_player"/&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/07/absolute-positioned-objects-hiding-behind-flash-animation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Design patterns &#8211; Part 11: Bridge pattern</title>
		<link>http://www.lotushints.com/2009/06/design-patterns-part-11-bridge-pattern/</link>
		<comments>http://www.lotushints.com/2009/06/design-patterns-part-11-bridge-pattern/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 07:00:38 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Code optimization]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[bridge]]></category>
		<category><![CDATA[custom classes]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[object-oriented]]></category>
		<category><![CDATA[Object-oriented development]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=361</guid>
		<description><![CDATA[In part 11 of Design pattern series we will go into creating and using the Bridge design pattern. It is moderately used and uses encapsulation, inheritance and aggregation to separate responsibilities into other classes. The Bridge pattern decouples an abstraction from its implementation so that the two can vary independently. Usage The pattern is most [...]]]></description>
			<content:encoded><![CDATA[<p>In part 11 of <a href="../category/design-patterns/">Design pattern series</a> we will go into creating and using the Bridge design pattern. It is moderately used and uses encapsulation, inheritance and aggregation to separate responsibilities into other classes.</p>
<blockquote><p><strong>The Bridge pattern</strong> decouples an abstraction from its implementation so that the two can vary independently.</p></blockquote>
<p><span id="more-361"></span></p>
<p><strong>Usage</strong></p>
<p>The pattern is most useful, when both classes (implementation and abstraction) are assigned to different task handling. In our example, we will look at how to separate data and actions to build a list of products and navigate it.</p>
<p><strong>Data representation class</strong></p>
<p>This is an abstract class with only navigational methods specified. Data representation class must implement navigational logic in its methods and thus assures that no other class will change or handle any properties without data representation class knowledge.</p>
<p>Also, for needs of our example, we will also define a type that will contain product id, name and price.</p>
<pre>Type TBridgeData
   strId As String
   strName As String
   dPrice As Double
End Type

Class CBridgeDataObject
   Sub NextRecord ()
   End Sub

   Sub PrevRecord ()
   End Sub

   Sub AddRecord (strId As String, strName As String,_
   dPrice As Double)
   End Sub

   Sub RemoveRecord (strId As String )
   End Sub

   Sub ShowRecord ()
   End Sub

   Function ShowAllRecords () As String
   End Function
End Class</pre>
<p><strong>Product data class</strong></p>
<p>Class itself inherits from Data representation abstract class. Also, it contains all navigational logic as well as data handling.</p>
<p>Beware that for this example, I did not actually load the data from the database. Instead I created five (5) products in the class construct. In real life, you should have read the data from your database!</p>
<pre>Class CBridgeProductData As CBridgeDataObject
   Private m_nCurrent As Integer
   Private m_AProducts () As TBridgeData

   Sub New ()
      m_ncurrent = 0

      Redim m_AProducts(4)

      m_AProducts(0).strId = "PR-0001"
      m_AProducts(0).strName = "Product 1"
      m_AProducts(0).dPrice = 100.00

      m_AProducts(1).strId = "PR-0002"
      m_AProducts(1).strName = "Product 2"
      m_AProducts(1).dPrice = 1000.00

      m_AProducts(2).strId = "PR-0003"
      m_AProducts(2).strName = "Product 3"
      m_AProducts(2).dPrice = 150.00

      m_AProducts(3).strId = "PR-0004"
      m_AProducts(3).strName = "Product 4"
      m_AProducts(3).dPrice = 400.00

      m_AProducts(4).strId = "PR-0005"
      m_AProducts(4).strName = "Product 5"
      m_AProducts(4).dPrice = 330.00
   End Sub

   Sub NextRecord ()
      If (m_nCurrent < Ubound (m_AProducts)) Then
         m_nCurrent = m_nCurrent + 1
      End If
   End Sub

   Sub PrevRecord ()
      If (m_nCurrent > 0) Then
         m_nCurrent = m_nCurrent - 1
      End If
   End Sub

   Sub AddRecord (strId As String, strName As String,_
   dPrice As Double)
      Dim n As Integer

      n = Ubound (m_AProducts) + 1
      Redim Preserve m_AProducts (n)

      m_AProducts(n).strId = strId
      m_AProducts(n).strName = strName
      m_AProducts(n).dPrice = dPrice
   End Sub

   Sub RemoveRecord (strId As String)
      Dim n As Integer
      Dim m As Integer
      Dim nCount As Integer
      Dim nIndex As Integer

      m = 0
      nIndex = -1
      nCount = Ubound (m_AProducts)
      For n = 0 To nCount
         If (m_AProducts (n).strId <> strId) Then
            m_AProducts (m).strId = m_AProducts (n).strId
            m_AProducts (m).strName = m_AProducts (n).strName
            m_AProducts (m).dPrice = m_AProducts (n).dPrice
            m = m + 1
         Else
            nIndex = n
         End If
      Next

      Redim Preserve m_AProducts (nCount - 1)
      If (m_nCurrent > n) Then Call Me.PrevRecord ()
   End Sub

   Sub ShowRecord ()
      Dim strDisplay As String

      strDisplay = m_AProducts (m_nCurrent).strId &#038; { } &#038;_
      m_AProducts (m_nCurrent).strName &#038; { €} &#038;_
      m_AProducts (m_nCurrent).dPrice

      Messagebox strDisplay
   End Sub

   Function ShowAllRecords() As String
      Dim n As Integer
      Dim strDisplay As String

      strDisplay = ""
      For n = 0 To Ubound (m_AProducts)
         strDisplay = strDisplay &#038; Chr(13) &#038;_
         m_AProducts (n).strId &#038; { } &#038;_
         m_AProducts (n).strName &#038; { €} &#038;_
         m_AProducts (n).dPrice
      Next

      ShowAllRecords = strDisplay
   End Function
End Class</pre>
<p><strong>Product base class</strong></p>
<p>Now, that we have our data classes created, we need to build an abstraction class that will call actual navigation and display the list contents or item if necessary. As we might have multiple classes that should have same functionality, it is a must to create a base class first. This class will encapsulate Data representation abstract class.</p>
<pre>Class CBridgeProductBase
   Private m_DataObj As CBridgeDataObject
   Private m_strGroup As String

   Public Property Get Data
      Set Data = m_DataObj
   End Property

   Public Property Set Data
      Set m_DataObj = Data
   End Property

   Sub New (strGroup As String)
      m_strGroup = strGroup
   End Sub

   Sub Next ()
      Call m_DataObj.NextRecord ()
   End Sub

   Sub Prev ()
      Call m_DataObj.PrevRecord ()
   End Sub

   Sub Add (strId As String, strName As String, dPrice As Double)
      Call m_DataObj.AddRecord (strId, strName, dPrice)
   End Sub

   Sub Remove (strId As String)
      Call m_DataObj.RemoveRecord (strId)
   End Sub

   Sub Show ()
      Call m_DataObj.ShowRecord()
   End Sub

   Sub ShowAll ()
      Messagebox "Product group: " &#038; m_strGroup &#038; Chr (13) &#038;_
      m_DataObj.ShowAllRecords()
   End Sub
End Class</pre>
<p><strong>Concrete product class</strong></p>
<p>Concrete product class in our case, will only be used to alter presentation when ShowAll method is called. This is not a must.</p>
<pre>Class CBridgeProducts As CBridgeProductBase
   Sub New (strGroup As String)
   End Sub

   Sub ShowAll ()
      Messagebox "Displaying all products"
      Call CBridgeProductBase..ShowAll ()
   End Sub
End Class</pre>
<p><strong>Implementation</strong></p>
<p>For test purposes, I have created an agent that will:</p>
<ul>
<li>create product list</li>
<li>navigate forward and backward</li>
<li>add an item to the list</li>
<li>remove an item from the list</li>
<li>display single product or all products at any time,</li>
</ul>
<pre>Sub Initialize
   Dim products As CBridgeProducts
   Dim data As CBridgeProductData

   Set products = New CBridgeProducts ("product group 1")
   Set products.Data = New CBridgeProductData ()

   Call products.Show ()
   Call products.Next ()
   Call products.Show ()
   Call products.Prev ()
   Call products.Show ()
   Call products.ShowAll ()

   Call products.Add ("PR-0010", "New product", 1475.00)
   Call products.ShowAll ()
   Call products.Remove ("PR-0004")
   Call products.ShowAll ()
End Sub</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/06/design-patterns-part-11-bridge-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

