If you try to display a value without specifying a scope, it first looks the value in the pageScope, requestScope, sessionScope and finally applicationScope. If it finds a value it displays otherwise it display ‘empty‘. Remember you won’t see null in the expression language.

For on-line retail companies it is very common to send confirmation when a customer places an order. Not all developers may install SMTP servers or comfortable with receiving all those test emails in their mailbox.

In ATG you can view the content without actually sending the email, by setting dummyMode property to false of SMTPEmail component.

Here is the direct link to dummyMode property of SMTPEmail component:http://<your_server&gt;:<port>/dyn/admin/nucleus/atg/dynamo/service/SMTPEmail/?propertyName=dummyMode

ATG terminology can be tricky. One of these tricky term is getvalueof in dsp tag. If you are new to ATG, you may think this is getting something, however it actually creates a variable in a given scope or in page scope if none specified.

With <dsp:getvalueof you can create a constant, param or a constant value.

We as software engineers read the code more than we write. Sometimes we end up legacy code hard to understand and maintain it. Recently we encountered a problem in extending a business logic, where we added the business logic to business logic tier, only to find that the business logic was never applied. The implementation in the business tier is correct, however we are not getting the results we wanted. Upon further investigation and debugging, the persistence tier is just adding the default values no matter what business tier is asking to do. The legacy code worked perfectly at that time it was written because it was called only once from business tier and it was setting default value explicitly (basically the default behavior was duplicated in persistence tier). The moment we tried to reuse the code with non-default behavior it started to giving incorrect results. We found the problem and refactored the code to remove the default behavior from persistence tier and added the required logic in the business tier.

This incident thought me one valuable lesson. Each tier in the architecture should do what is supposed to do. Nothing more and nothing less. If you observe a tier is doing more than what is supposed to do, remove the extra stuff, place it where it belongs. It’s like Single Responsibility Principle but at a higher level.

We all wish the code need to work on is well-maintained, easy to enhance and easy to test. However if you have work with legacy code it’s different ball game. Imagine a real life situation where you add features to existing spaghetti code and two weeks later you need to rollback (which tells why you have spaghetti code in the first place).

Most people write a test case for the required feature and make it fail, add new feature and make the test pass and refactor the code to remove duplicate code and make sure the test pass and all of the other tests pass. This is a typical approach and usually works most of the time as long as you are not required to rollback the features you added. As soon as you want to rollback the features, you faced with dilemma that whether you want to rollback everything including the refactored code or just the features you added. However if you rollback everything, you end-up loosing all your refactored code. If you want to remove only features you need to comb the code to make sure you didn’t leave any residue of the new features.

Here is a different approach, whenever you encounter unmanageable code, write a test case (if there is none) first to make sure it checks the existing functionality. Refactor the code to the point so that you can understand the code as well all the tests pass. Commit the code so that you don’t loose all your refactored code. Now add a test case to check the new features you are going to develop, make it fail and change the source code, make test case pass, refactor it, make sure all the tests pass. If you ever need to rollback the feature, you have a base point to rollback. In this approach, it’s easy to rollback and still keep all the refactored code so that if you visit next time, you don’t have spend another session of cursing the spaghetti code.