Thursday, December 28, 2006

TDD

Test Driven Development

  • The importance of writing tests
    • They force the developer to think of the class design
    • They provide a safety harness while refactoring
    • They ensure that the state of code is always stable
    • New developers can make changes comfortable with the knowledge that if they break something that was working, the tests will inform them
    • Test after development is not the same as test first development. Test after development does not reap all the benefits of test first development
  • Writing the tests
    • Think about the class it’s responsibilities and it’s API
    • Write the tests to test every method and various conditions in the methods
    • Whenever you think of writing a print statement or generate a log, it might be a scenario to include a test
    • Write enough production code to ensure that the tests compile and fail
    • Write production code to pass all tests one by one, while also ensuring that previous tests do not fail
  • What not to test
    • Database entities need not be tested
    • Do not go overboard with tests. First write tests that are most likely to fail. Think of the cost benefit ratio while writing tests
  • The test class
    • Tests classes end with the work Test. The test class for Account will be AccountTest
    • Test methods begin with the word test. The test method for creditAccount() will be testcreditAccount()
    • Tests can either exist in a different source tree in the same package as the class they are testing, or in the same source tree, but in a different package.
  • Managing dependencies
    • Unit tests should ideally not have any dependencies
    • Dependencies can be eliminated with mock objects (so that units can be tested in isolation)
  • AllTests
    • There should have one class AllTests that will run the entire test suite

    Requirements (Java Unit Tests):

    • JUnit 3.8 for JDK 1.4 and before
    • JUnit 4.x for JDK 1.5 and after
    • StrutsTestCase for testing Struts Action classes

    References:



Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net

Wednesday, December 27, 2006

Agile Timeboxing

A few days back, I was discussing Agile Timeboxing and estimation with some developers. What follows are some suggestions I gave them and thoughts that emerged from the suggestions.

In the examples I have used to explain certain points, I have assumed a J2EE application which has a database, an entity layer, an application layer, Struts Action classes, and JSP's. The concepts can be extrapolated into any other type of application as well.


Given a requirement we should be able to determine the amount of time it will take us to fulfill it. This is much easier said than done. Some reasons why we are not able to come up with accurate estimates are:
  • Lack of familiarity with the code base

  • Overestimating our capabilities

  • Underestimating the amount of work needed to be done and it's potential ripple effects

  • Working with gut feel without a proper process to identify the work that needs to be done

In this post I will focus on a process that can be used to identify the amount of work that needs to be done to fulfill a requirement. Once we know the amount of work or it's complexity, the team will have to correlate it to a time frame based on their capabilities.


Let's start with the requirement given by a client. We first need to ensure that it is not very complex and large. If it is, then break it down into manageable sub-requirements. Then break down each of these into tasks. These tasks should ideally be vertical and not horizontal (in your system architecture). So for example, if you are required to modify the design of a few tables and add some business logic, the tasks should NOT be “modify database schema”, “update all classes in the application layer”, “update all Action classes”, and so on. The problem with this approach is, when you modify the database schema, the application will have broken, and will remain unstable until the last task has been completed. It is not a good idea to keep the application unstable for such a long time. Ideally we want the application to come back to stability as soon as possible. Hence, we create tasks along vertical lines, such as “update USER table and support the new field in the view”. This will entail updating the table and all corresponding layers that are affected by that entity. By creating vertical tasks, we ensure that the software will become unstable only as long as we are working on that task. The software will be back in a stable state as soon as we complete the task. A simple rule of the thumb is, a task should not take more than 16 hours to complete. Break tasks that take a very long time to complete, into smaller tasks.


Once we have identified tasks, we have to estimate the time effort. Most of the time developers work on gut feel, but it may lead to extremely inaccurate results. Every task consists of either modifying existing classes or adding new classes. Work your way up the layers of the software and identify all the classes that will have to be modified or added to fulfill that task. For example if we are required to add a new field 'domain' to the login form, we know the USER table has to be modified, and the corresponding entity has to be updated. We then identify all the classes in the application layer that will be affected by the USER entity, followed by all the Action classes and the JSP's. If any new classes need to be created then add them to the list as well. Your IDE can be very helpful in identifying dependencies. After we have outlined all the classes that will be affected or need to be added, we should determine the complexity of work to be done on each class. A simple way is to assign a complexity level of simple, medium, or complex to each class. There are several ways to determine the complexity. One of them is to use the number of unit tests generated to guess the complexity. To understand the complexity, we begin writing unit tests for each class. Since we are still in the estimation phase, we do not have to write the test bodies. It will suffice to write the test methods with a single 'fail()' statement. Be sure that each test, tests one and only one thing, and all possibilities of failure and success are covered by the tests. The number of tests generated will give a fair indication of the complexity involved in updating/creating that class. Since the definition of complexity as well as the team's capability differ, the amount of time a team takes to complete tasks at a complexity level will vary from team to team.


A possible result of this phase will be a table similar to the one below.



Simple

Medium

Complex

Classes

6

2

1

Time (Hrs)

2

4

8

Optimistic Estimate

12

8

8

Multiplication factor

1.5

1.5

1.5


18

12

12

Buffer

20%

20%

20%

Final Estimate

21.6

14.4

14.4


Estimate: (21.6 + 14.4 + 14.4) = 50.4 hrs = approx 50 hrs


The table above shows the effort required to complete a task. We have identified simple changes in 6 classes, medium changes in 1 class, 1 new class of medium complexity, and complex changes in 1 class. Note that we do not differentiate for classes that need to be modified and classes that need to be added. We simply write 2 classes of medium complexity (even though one is to be updated and one is a new class). As we mentioned earlier, every team will have their own correlation of complexity to time. Let us assume that complexity estimates for our team are 2 hours for a simple tasks, 4 hours for medium, and 8 hours for complex tasks. Next we multiply the number of classes with the time. Our first estimate is usually optimistic and must be multiplied by some factor to account for the unknowns like code explorations, technology road blocks (like having to work your way around some potential limitation of Struts), some classes that were missed out in the impact analysis or any other unknown factor. A multiplication factor brings our estimate closer to reality, but in my experience we still have to account for extra time taken due to integration issues, minor requests from the clients, etc. It is usually a good idea to add a buffer of 20% to account for these factors. After applying the multiplication factor and the buffer we add up values in all the 3 columns to get the final estimate.


Once we have estimates for all the tasks, developers are ready to pick them up. In the IPM each developer usually gives his or her available time in the next iteration, and picks up tasks such that they do not add up greater than the available time. We usually assume that all the available time will e spend in coding. We do not consider time spent in client conference calls, email and IM communication, planning for the next iteration, reading necessary documents, etc. The amount of time we will actually have for development is our availability subtracted by time taken for ancillary tasks. Always keep this in mind before picking up tasks.


This is a very practical process for time boxing tasks, that I have often found useful. Several things in this process, like the multiplication factor, buffer, and ancillary tasks are team and project dependent. Appropriate values that better resemble your project and team capabilities may have to be used. The presence of a multiplication factor should not be used as an excuse for lax estimation. It is used to initially account for lack of familiarity with the domain and code base, but should be adjusted as the team gets better at estimating.



Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net
Here are the comments from the original post

-----
COMMENT:
AUTHOR: Chris
EMAIL:
URL:
DATE: 12/30/2006 05:28:03 AM
I have used a similar technique to estimate. I would simply multiple my gut feel with 3. This almost always produced reasonably accurate estimates.

Friday, December 08, 2006

A very informative website

A few days back I came across a very good and informative website. Before you say to yourself... oh no not another website, and skip this post, let me tell you that this one is really good. Like all good things it is community driven. The community bring up the latest new items related to software development on the website, but the most useful content according to me is their interview series. They have interviewed several software luminaries like Joshua Bloch (on API design), Martin Fowler (on DSL's), Ron Jeffries (on Agile), Brian Goetz (on concurrency in Java), and many more. These interviews  are available for viewing on their website. The overall content quality is superlative.

I'm sure I have at least got you interested enough to check it out.

Monday, December 04, 2006

MAX Memory For Your JVM

There is an interesting discussion going on the Java Posse Google Group on the maximum memory that can be allocated to a JVM.

Now if you are running a 32-bit system, then 4 GB is the maximum addressable memory. Of this, the OS (Windows)  takes about 2 GB (though it can be tweaked to take less according to a post on the Java forum), leaving 2 GB for your apps. You could theoretically assign this 2 GB to your JVM, but thread stacks are allocated memory outside of the JVM. So if your application uses a lot of threads, you will have to leave some space for the thread stacks.

Now if you use a 64-bit system, then you can allocate a LOT more memory to your JVM, but to do this your entire stack (CPU, OS, JVM, any other dependencies) needs to be 64-bit compliant. 

If you want an unlimited heap size for your JVM, you might want to check out Azul. John Reynolds wrote an interesting blog on scaling JVM's with Azul. 

By the way of you enjoy listening to podcasts and are into Java, then you absolutely must listen to the JavaPosse podcast. It is very informative and entertaining.



Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net
Here are the comments from the original post

-----
COMMENT:
AUTHOR: Amish
EMAIL:
URL:
DATE: 01/17/2007 10:00:39 PM
hey.. sourceforge has serverfarm which they share with developers to work on it. You might be able to try various hardware available with them to check performance of systems and jvms...

COMMENT:
AUTHOR: Parag
DATE: 01/18/2007 05:30:14 PM
Hey Amish,
Good to hear from you. That is a good idea to check for peformance.

I will checkup with them for access, meanwhile, do you know if we need to apply or we can just create an account somewhere and start using their servers?

--
Parag

Thursday, November 30, 2006

Coding Dojo FAQ

The concept of coding dojos has been generated a lot of interest lately. Some people mailed me to learn more about coding dojos, how to conduct them, and how they can help an organization. So I decided to set up a FAQ. But before I say anything more, the credit for this concept goes to Dave Thomas who conceptualized the idea of coding katas (similar to dojos but to be done individually).
 
Q1. What is a coding dojo?
A1. A dojo is a exercise that brings the element of practice to programming. It lets developers explore various solutions and approaches to a problem without time pressures. Just like musicians and sportsmen practice to improve their skills, these exercises help raise the bar of a programmer's skills.
 
Q2. How is a dojo conducted?
A2. The dojo begins with the facilitator/coach explaining the problem statement to the group, followed with a quick design discussion. Once everyone has understood the problem, the first pair starts programming while the others watch on the projector screen. The audience should be a participative audience and not a passive one. They should point out alternate solution paths and mistakes. Everyone should contribute their knowledge. After 20 minutes the first pair returns to the audience and the next pair continues programming from where they left of... and so on. It is the responsibility of te programming pair to ensure that everyone in the audience understands what they are doing. If someone has a doubt, they can stop the pair and request them to clarify what they are doing.
 
Q3. Are there other learning opportunities for the participants besides "raising the bar of programming skills"?
A3. A lot of "technology learning" can also happen as a side effect. When I conduct dojos for clients, I take every opportunity to transfer technology specific knowledge every time an opportunity arises. For example, once we needed to use some IO classes, and I spoke to the group about the IO and Reader hierarchies and about the Decorator design pattern. Once we needed to implement a callback, so I took the opportunity and explained anonymous inner classes and callbacks. Several learning opportunities will arise, but they will usually change with each exercise.
 
Q4. What kind of equipment do we need to conduct a dojo?
A4. A computer loaded with necessary software and a projector.
 
Q5. What software needs to be loaded on the computer?
A5. Assuming you will be working in Java: JDK(1.4+ is a good idea), an IDE (Eclipse, NetBeans...), JavaDocs for the JDK classes, and any other tools, libraries that are specific to the exercise.
 
Q6. How many participants can attend a dojo?
A6. Between 4 - 16. Try not to exceed 16.
 
Q7. How long is a typical coding dojo?
A7. It depends on the exercise. In my opinion, for ant meaningful learning to happen you need about 4 - 6 hours.
 
Q8. Can I take a large exercise and break it into multiple dojo sessions.
A8. Well, it can be done, but I will not recommend it, because breaking up will mean that participants have to spend time remembering what they did in the last session. This break in the may waste some time and reduce the learning.
 
Q9. Can a dojo be conducted without a coach/facilitator?
A9. Yes, but that will work well only with a group of experienced developers.
 
Q10. What are the skill levels needed to participate in a dojo?
A10. Fresh developers to very experienced programmers can all benefit from a dojo. Software development is an art and there is always scope for improving skills. However I will suggest that participants have academic exposure to the programming language in which the dojo will be conducted.
 
Q11. What kind of a mix of people (from a skills perspective) is best for an effective dojo?
A11. Having a group of similarly skilled people usually works out better. Even though this can be subjective, a good guideline is to group people with the following experience ranges together: 6 months - 12 months, 12 months - 36 months, 36+ months. Again, this is very subjective, and your mileage may differ.
 
Q12. Can dojos be used to explore refactorings?
A12. Yes, infact they can be used very effectively to understand refactoring principles. In this case the dojo starts with smelly code that needs refactoring, and the exercise is to refactor the code while discussing pros and cons of each refactoring.
 
Q13. Can dojos be used for anything else?
Q13. I think dojos can be used as a learning tool to understand any concept that needs hands-on practice and an exchange of ideas. Design patterns, test first development, pair programming, specific API's and probably many other skills can be learned very effectively with dojos.
 
Q14. Are there any links to resources and example exercises?
A14. You must check out Dave Thomas' excellent page
 
Q15. Do you conduct dojos?
A15. Yes I do. I conduct open as well as inhouse dojos in Pune, India. If you are located elsewhere, I will be glad to share my experiences and help you conduct the dojos yourself. You can mail me at - info (at) adaptivesoftware (dot) biz
Alternately, you can also post your questions as comments to this post. I will be gald to answer them here. 

Monday, November 27, 2006

Unconferences and open spaces

Bruce Eckel and several other people have been experimenting very successfully with unconferences and open space conferences. On the face of it "open spaces" seems to a very broad (open) ended concept, but it can be a very interesting and powerful concept if the participants are mature enough to make proper use of it. Here is the broad outline of my understanding of open spaces:

Open spaces are conferences propelled by a concept or question. The driving concept could be anything from "How do we make our neighborhood cleaner" to "What is the best way to utilize web services". These are not preplanned conferences. The person or organization who wishes to explore a concept/problem will send out invitations in the community. People/companies who have similar interests will accept the invitation to attend. An invitation fee is usually charged to compensate for food, equipment, and conference room costs. The conference is a self organizing conference, which means there is no pre-planned agenda. However the duration of the conference and time slot place holders are pre-determined. The time slots are later filled with a concrete agenda. On the day of the conference the initiator gives a keynote presentation on the main issue, after which participants volunteer topics that they would like to explore under the main umbrella. Each participant who volunteers a discussion fills up a time slot and place. Those with similar interests also sign up. Note that all time slots and spaces may not be signed up for. More topics may emerge after the discussions start.

Once the self organizing agenda has been determined, participants group up in various corners or wherever they want to, and discuss the issue they signed up for. Participants may move around from one group to another or may stay with a group for the planned duration. The person who initiated a particular topic is responsible for maintaining the transcripts and documenting any interesting findings or observations. On the last day all conversations are consolidated by the lead participants (participants who initiated discussion topics) by briefly telling everyone what was discussed and any interesting findings that may have emerged. Important findings and insights are noted and may be published on a website or a technical journal for later reference.
 
Open spaces has a huge potential for learning and education. We are living in a time when technology is changing very rapidly and people have different learning requirements for the same technology. For example different developers who want to learn about multi-threaded programming will most likely want to learn it at different levels. Some might want to just scratch the surface to understand concurrency, while other may want to learn in greater detail to write code that uses concepts of multi-threading, while a few people might actually want to gain a high degree of expertise in it, to create a multi-threaded server. Couple this with the fact that different people also have different learning speeds, and you will soon realize that a traditional workshop to teach "multi-threading in Java" is going to yield sub-optimal results.
 
What we need is an environment where people can pursue their learning needs at a speed and depth of their choice. I think open spaces offers one way to create such a personalized learning environment. 
 
Links:


Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net
Here are the comments from the original post

-----
COMMENT:
AUTHOR: ranjan
EMAIL:
URL: http://ranjanjha.blogspot.com
DATE: 11/28/2006 01:05:03 PM

I hope to attend( I am in the wait list) the ' unconference' by Global Voice(http://www.globalvoicesonline.org) in Delhi on 16th Dec ...
Thanks a lot for this post sir..
I know what an unconference is ... otherwise I always thought its just on of the spelling mistakes that people make :)

COMMENT:
AUTHOR: Parag
DATE: 11/29/2006 08:07:35 AM
That's nice Ranjan. Do blog about your experience and let us know what it was like.

--
Parag

Monday, November 20, 2006

Java infrequently answered questions

Peter Norvig has an excellent list of Java related IAQ's (Infrequently Answered Questions) on his website. He talks about stuff that cover various subtleties in Java. Here's an example:

Q:Within a method m in a class C, isn't this.getClass() always C?

No. It's possible that for some object x that is an instance of some subclass C1 of C either there is no C1.m() method, or some method on x called super.m(). In either case, this.getClass() is C1, not C within the body of C.m(). If C is final, then you're ok.

-- Peter Norvig

 




Free Web Based Courses On Java Programming Best Practices and Obect Technology and Design 

Thursday, November 16, 2006

Learnings from a discussion on EJB 3.0

Yesterday I had a learning discussion session with some developers on EJB 3.0 It was a very interesting discussion and we all took home some new and interesting stuff. The key learnings were:

  1. EJB 2.1 was a 300 lb gorilla that used a crane to lift a peanut. EJB 3.0 is a nimble chimpanzee :-)
  2. EJB 3.0 uses annotations instead on the xml deployment descriptors that were so hard to maintain. So beans, security constrains and everything that was earlier defined using the deployment descriptor can now be done in code using annotations. I think this is really neat, especially for small applications.
  3. We no longer need to define all the 2.1 interfaces to get an EJB working. In fact we need not define interfaces at all. A business interface will be automatically created for us by the annotation processor. I read somewhere on the net (do not remember where), that we must not generate the business interface automatically (but create it manually and have the EBJ implement it), because the automatically generated interaface will include every public method from the bean and make it available to client code. Now I think that should not be a problem. Public methods are meant to define the public interface of a class, so if we do not want client code to invoke a method, then it should not be public. So the existence of public methods that should not be available to client code, smells to me of bad design.
  4. EBJ 3.0 entity beans are now POJO's, which is again really nice and makes development light weight. Again a big plus for small applications, and for maintainability.
  5. EBJ 3.0 uses dependency injection. The container will inject environment related objects in the client automatically. Client code now does not need to do any complex JNDI lookups. By the way Martin Fowler has written an excellent article on dependency injection here.
  6. We can still use deployment descriptors to override annotations, but in my opinion this should be avoided (unless absolutely necessary), because it will make the application harder to maintain.
Overall EBJ 3.0 is a huge advancement towards easing enterprise development. I am certain this specification will be adopted and accepted by the developer community much better than the previous one.

Saturday, November 11, 2006

Coding dojo

Last Saturday we conducted a coding dojo session for a software development company in Pune. A coding dojo is an exercise that brings the element of practice to programming. All sportspersons, musicians... practitioners of any craft, do a lot of practice, where they explore various aspects of their art, explore different techniques, tools, and solutions. But software developers never do that. The way they enhance their skills is by learning while working or traditional workshops.

Workshops are a good way to bring a group of people up the learning curve on a new technology, but they fall short when we use them to improve developer's programming skills. Programming skills are best improved by practice. Practicing alone is good, but practicing with a group and a mentor is even better. This is exactly what a dojo is. A group of software developers that gets together to practice programming, to explore solutions, learn and improve their programming skills in the process.

For this dojo, we decided to code Dave Thomas' Kata 4 - Data Munging. We were a group of six developers. After an explanation of the exercise, we started programming in pairs, but not all at the same time. What we actually did was projector programming. The first pair started coding and the rest watched as a participative audience. By participative I mean, they were not just watching, but also suggesting solutions, pointing typos, and generally participating in the solution. After 20 minutes, the first pair went in the audience and the next pair took over for the next 20 minutes... and so on.

Here's what we had after completing part 1 (Weather data) and part 2 (Soccer data).  

DataMunging.gif 

WeatherMain.java drove the weather data. Actual parsing of data was done by WeatherDataParser.java and WeatherData.java represented the data. Ditto for soccer data.

Part 3 of the coding kata is DRY fusion. We have to identify repititive code and refactor it so that it follows the DRY (Don't repeat yourself)  principle.

I would like to urge you to actually program the solution as explore how we can elliminate duplicate code. We can elliminate duplication with inheritance or with composition. I am inclined to use composition as the first choice because inheritance trees are more difficult to maintain, and also since polymorphism is not warranted here. Your views however might differ, and if they do, please write about them as a comment here or as a trackback to your own blog.

We will solve the DRY fusion problem this week, and will explain the solution here. 

Thursday, November 09, 2006

Ending notes on software design series

Software design is all about decontructing a system into manageable units, identifying relationships among them and getting the units to interact to fulfill system requirements. To become a good object oriented designer, you first have to replace the "procedural mindset" with an "object oriented" one. That, however is not as simple as it sounds. The best way to get there is by practice, lot's of it. Take every opportunity to create a good design.

When creating an entire system, think about the classes, their relationships, and interactions. When creating a class, think of what responsibilities it should fulfill. What should the API be like? How does it relate to other classes? When creating methods, think about the method signature and about the code in the method. Does the method do one and only one thing? What exceptions should it throw? Is is intuitive and easy to use? At whatever level you are creating the system, you can always think of design. Remember, there is a lot of power in the process of understanding, reflecting, practicing, and writing. Use it to learn continuously.

The natural progression after understanding basic design principles is understanding design patterns and then enterprise architecture. Start with the "Gang Of Four's" design patterns and then move towards more complex topics.

A few good resources for for reference:

 

I hope you have enjoyed this course and found it useful. Good luck... and wishing you have a very successful and enjoyable career in software development.

Wednesday, November 08, 2006

Your feedback on translating requirements into system design

Please take a couple of minutes to give your feedback on this section. Would you like to see any additions, subtractions, or changes? How did you like the audio and video descriptions used in this section? I know they are not optimal, and I hope to improve them, but it will really help me if I get feedback on exactly what should be improved to make the course more effective for you.



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Friday, November 03, 2006

What is object oriented programming - by Alan Kay

Alan Kay coined the term object oriented programming in the 60's. Even though the progression of this paradigm has been a collaborative effort, Alan Kay has played a very important part in the creation of this paradigm.

In 2003 Stephan Ram could not find an authoritative source on what "object oriented" really meant, so he decided to ask Alan Kay himself.

Here's a link to his reply. A must read for anyone who is interested in object oriented programming and design.

Thursday, October 26, 2006

Identifying interactions











[Time 5:50 mins]


In this section we will identify collaborations among the classes as they enact each use case. In this phase we may discover new classes that we had not thought of earlier, as well as new responsibilities for existing classes. We may also discard some initial classes. The process of determining the collaborations as each use case is enacted helps in refining and validating the design.


CUSTOMER DETERMINES THE PRICE OF A GROUP OF ITEMS:

  1. Customer enters item codes at the UserTerminal
  2. UserTerminal creates Item objects for each item and finds out their individual prices
  3. The UserTerminal finds out all the schemes these items belong to
  4. The UserTerminal determines the Scheme price of all items belonging to a Scheme and adds the individual price of the remaining items
  5. The UserTerminal displays all the above information to the Customer

 

CUSTOMER CHECKS OUT ITEMS:

  1. Customer takes items to the checkout system
  2. Checkout assistant adds item codes in the CheckoutSystem
  3. Checkout system determines the price of all the items, taking into account discounts and schemes
  4. Checkout system generates a bill for the customer
  5. Checkout system accepts the customers payment

 

STOREMANAGER DETERMINES THE SHOP INVENTORY VALUATION

  1. The StoreManager uses the ControlPanel to get inventory vauation
  2. The ControlPanel uses the CurrentStock to get the valuation
  3. The CurrentStock object determines the price of every individual item and the price of items and represents it as the maximum price in the PriceRange
  4. The CurrentStock determines the minimum price by associating items into schemes and assuming that they are sold such
  5. The CurrentStock returns the PriceRange object back to the ControlPanel which displays the details to the StoreManager

New classes identified:

  • UserTerminal
  • CheckoutSystem
  • PriceCalculator
  • ControlPanel
  • PriceRange


Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Wednesday, October 25, 2006

Identifying responsibilities











[Time 2:04 mins]


Here I have listed classes from the previous post and associated responsibilities to them.

Customer
- To shop
- To pay for the items

Item
- Holds an item code
- Has a cost
- Has a price

Scheme
- Holds a scheme code
- Has a price
- Contains a list of other Items

Price
- Holds the price (for an item)

DiscountedPrice
- Holds the price
- Holds the discount

PerUnitPrice
- Hold the price
- Holds the unit for the price

Unit (and subclasses)
- Specifies a unit
- May have methods for converting between units.

StoreManager
- Checks the audit trail of items sold
- Determines the value of current in-shop inventory

CurrentStock
- Contains a list of all items in the shop 



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Refine classes











[Time 6:29 mins]


Now that we have identified some basic classes, some questions come to mind. Let us ponder a bit over these questions. We might identify new classes or remove some old ones at the end.

  • Do we need different types of customers
  • Do we need to represent simple and complex items differently?
  • How do we represent different types of prices?
    • Attributes vs sub classes
  • How do we represent units?
So now we have added a few classes:
  • PriviledgedCustomer (maybe... let me ask the client)
  • DiscountedPrice
  • PerUnitPrice
  • Various Unit subclasses
This is by no means the final class list. As we identify responsibilities and collaborations, we will further refine this class list.


Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Identify classes











[Time: 2:00 mins]


Supermarket Classes 

  • Customer
  • Item
  • Price
  • Unit
  • Scheme
  • StoreManager
  • CurrentStock


Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Class and communication diagrams











[Time: 7:07 mins]


We have identified classes, their responsibilities, and interactions among them as they enact use cases. Shown below is a class diagram and several communication diagrams that outlines important classes, their relationships, and collaborations among them. I have not shown all the classes, but only the ones that are important and have relationships with other classes. Classes that are not shown include:

  • Customer
  • StoreManager
  • UserTerminal
  • ControlPanel
  • CheckoutSystem

http://www.adaptivesoftware.biz/storage/images/supermarket_classes.gif  

 Figure 1

 

Communication Diagrams:

Customer determines the price of a group of items

http://www.adaptivesoftware.biz/storage/images/cust_queries_price.gif 

 Figure 2

 

Customer checks out items

http://www.adaptivesoftware.biz/storage/images/cust_checksout.gif

Figure 3 

 

Store Manager valuates in-shop inventory

http://www.adaptivesoftware.biz/storage/images/store_inventory_valuation.gif 

Figure 4 



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Translating requirements into system design - A case study

In this section we will take a requirements document for a software system and create a system design from it. The statement for the excercise has been inspired by Dave Thomas' coding kata #1. Let's build a system for a supermarket. Here are the requirements.

The supermarket has various items for selling. Each item has a price. Sometimes an item may have a discounted price, and sometimes it may be part of a scheme. Schemes could be similar to buy two get one free, or buy a certain quantity of an item and get another item free. Items may also be priced for a certain unit. For example Apples may be Rs 40/Kg, however they can be sold in a fractional unit also 500 gms. Some items may be simple, like a can of Pepsi or complex like a crate of 10 Pepsi cans. The sytem should also maintain an audit trail of all sold items for future evaluation.

The store manager should be able to get a valuation of the current stock.

When a shopper checks out items the system should calculate the most optimum price based on schemes that the items may be part of.

Please Note: To keep the exercise simple we do not concerning ourselves with inventory. We only consider items and pricing.

Here are the use cases for this exercise.

supermarket_usecases.gif 

Resources:

  1. Dave Thomas' coding kata's 

Tuesday, October 24, 2006

Your feedback on principles of object oriented design

Please take a couple of minutes to give your feedback on this section. Would you like to see any additions, subtractions, or changes? How did you like the audio and video descriptions used in this section? I know they are not optimal, and I hope to improve them, but it will really help me if I get feedback on exactly what should be improved to make the course more effective for you.



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Monday, October 23, 2006

Using inheritance and composition






  • Inheritance is used for
    • Code resuse
    • To support polymorphism
  • Disadvantages of inheritance
    • Difficult to change the interaface of the subclass
    • Superclass is always instantiated
    • Can get complex and unmanageable
  • Composition is used for code reuse
  • Disadvantages of composition
    • We cannot use polymorphism
    • We cannot extend the system by adding subclasses
    • May have a slight performance overhead
  • Usage
    • Inheritance: IS- A
    • Composition: HAS - A





















Example 1



public class Car {



    private Engine engine;



    public void start() {}



    public void stop() {}







public class SUV extends Car{



    public void start() {} //overrides the start method from Car

 



    public void fourByFourMode() {}



}







Example 2:



public void someMethod() {

    Car c = new SUV();

    c.start();

}







Example 3:



public class Car {



    private Engine engine;



    public void start() {

      engine.start();

        //maybe do something more

    }



    public void stop() {}



}




Java2html




Resources:



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

High Cohesion












[Time: 4 mins]


  • Stuff that goes together, stays together
  • Easy to discover relevant code
  • Levels of cohesion
    • packages
    • classes
    • methods 
 
So in very simple words, cohesion is keeping related stuff together so we can find what we want without too much difficulty. 
 

 





















Example 1

public class Student {

    //cohesive methods

    public void registerForCourse() {}

    public void deregisterFromCourse() {}

    viewTranscripts() {}

    //methods below are not in synch with the responsibilities of the Student class

    //hence cohesion is broken

    submit grades() {}

    submitCourseSchedule() {}

 





Java2html





Resources:
 


Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Sunday, October 22, 2006

Loose coupling






[Time: 4:32 mins]


Loose (or low) coupling means (in a generic sense) that an entity can interact with another entity without being concerned with the internal implementation, and through a stable interface. Low coupling is implemented by using principles of information hiding. When two entities are loosely coupled, internal changes in one of them do not affect the other. The calling method is coupled to the called method and not it's implementation. Since we have already discussed encapsulation and information hiding in detail, I will not repeat it here.

  • Loose coupling is achieved with information hiding
  • And by programming to the interface rather than the implementation

 

Example 1: Tightly coupled system 

public void aMethod() { 

    ArrayList myList = new ArrayList();

    doSomethingWithList(list)



private void doSomethingWithList(ArrayList list) {



Example 2: Loosely coupled system 

public void aMethod() { 

    List
myList = new ArrayList();

    doSomethingWithList(list)



private void doSomethingWithList(List list) {


Java2html
 
  • Loose coupling contains the scope of change when an implementation is modified 


Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Saturday, October 21, 2006

Don't repeat yourself

The code says everything once and only once, which is the essence of good design. -- Martin Fowler




[Time: 4:44 mins]


  • Repititive code makes maintainance more difficult
    • There are more places to change
    • We may forget to change some of them
    • Increases probability of bugs
  • Types of repitition
    • In methods in a class
    • Accross the entire software 


Example 1: DRY violated



















public class Account {

  public void transferFunds(double amt, Account dest) {

    //transfer funds

    //generate email... create connection

    //create message

    //dispatch email

  }



  public void delete() {

    //delete account

    //generate email... create connection

    //create message

    //dispatch email

  }

}




Java2html







Example 2: DRY honoured



















public class Account {

  public void transferFunds(double amt, Account dest) {

    //transfer funds

    dispatchEmail(...);

  }



  public void delete() {

    //delete account

    dispatchEmail(...);

  }



  public dispatchEmail() {

    //generate email... create connection

    //create message

    //dispatch email

  }

}




Java2html




Resources:

  • http://www.artima.com/intv/dry.html
  • http://c2.com/cgi/wiki?DontRepeatYourself
  • http://c2.com/cgi/wiki?OnceAndOnlyOnce



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Keep it simple



width="290" height="24" id="audioplayer2">



value="playerID=2&bg=0xCDDFF3&leftbg=0x357DCE&lefticon=0xF2F2F2&rightbg=0xF06A51&rightbghove

r=0xAF2910&righticon=0xF2F2F2&righticonhover=0xFFFFFF&text=0x357DCE&slider=0x357DCE&track=0x

FFFFFF&border=0xFFFFFF&loader=0xAF2910&soundFile=http://www.adaptivesoftware.biz/storage/audio/swdesignprinciples-keepitsimple.mp3" />





[Time: 5:37 mins]


One should not increase, beyond what is necassary, the number of entities required to explain anything - Occams Razor

  • KISS helps keep software manageable
  • The UNIX kernel is an example of a functionally complex software implemented in simple design
  • Intentional complexity
    • Enthusiasm to use design patterns
    • Enthusiasm to make a system uber flexible
    • Feature bloat
  • Unintentional complexity
    • Maintainance quick fixes
    • Laziness in refactoring

 

Design principles











[Time: 2:20 mins]



  • What is software design
  • Decomposition is done at various levels of granularity
  • We will focus on some simple principles that deal with classes, their responsibilities, and collaborations.

There are some well known software design principles that serve as guideposts for us in the design process. In this section we will discuss some of the most important principles. AS OF NOW THIS SECTION COVERS SOME BASIC PRINCIPLES. OTHER PRINCIPLES LIKE THE ''OPEN CLOSED PRINCIPLE", "LISKOV SUBSTITUTION PRINCIPLE", etc, WILL BE ADDED IN THE NEXT VERSION OF THIS COURSE.

Something to remember before moving ahead: 

While principles, patterns, heuristics, and guidelines offer valuable advice about how to do things the right way, they don't serve as substitution for thinking on our own. Unfortunately, I think we all too often let these principles, etc. do the thinking for us.

-- Kirk Knoernschild 



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Wednesday, October 11, 2006

Your feedback on goals of software design

Please take a couple of minutes to give your feedback on this section. Would you like to see any additions, subtractions, or changes? How did you like the audio and video descriptions used in this section? I know they are not optimal, and I hope to improve them, but it will really help me if I get feedback on exactly what should be improved to make the course more effective for you.



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

You will find below comments from the original post


COMMENT:
AUTHOR: Rashmi
DATE: 10/18/2006 05:50:25 PM
Sir could you please explain the difference between inheritance and composition through an example code



COMMENT:
AUTHOR: Parag
DATE: 10/20/2006 01:16:47 PM
Thanks for the suggestion. I will add an example to the blog post. Till then, here is a quick code sample.

//this class uses inheritance. Guitar inherits
//from MusicalInstrument
public class Guitar extends MusicalInstrument {
//...
}

//this is an example of composition. The class
//Car is composed of several instances of the
//class Wheel
public class Car {
Wheel wheels[];
//...
}

When a class has other class(es) as instance or class variables then a composition relationship is established between them.
Composition also allows code reuse. In the above example the class Car can invode methods of Wheel thus acheiving functionality without impemented it in it's own class.

Notice the relationship between the classes in both the examples.
A Guitar IS-A MusicalInstrument.
We typically use inheritance when there is an IS-A relationship between two classes.
A Car HAS Wheel(s)
We typically use composition between classes that have a HAS-A or HAS relationship.

now before I wrap up, a couple of questions. Why is it incorrect to use inheritance when there is a HAS-A relationship between two classes. More specifically why should we avoid...
public class Car extends Wheel {}

Here is a very good link that explains the concept in detail:
http://www.artima.com/designtechniques/compoinh.html

--
Parag

What about performance

OK, so there is a common myth about performance and good design being contradictory. It is said that we must often sacrifice good design for the sake of performance. Maybe so... but not always.

Good design is about proper decomposition of functional requirements, about proper modularization, non repitition, simplicity, reusability, proper use of inheritance hierarchies, and about containing the functionality.

There is no reason for most of the above to affect performance. However, sometimes we create good design by adding layers and indirection. This may result in extra method calls and perhaps creation of a few more classes. This may somewhat affect performance of the application, but again if the application in question is a web based one, then the performance hit will be negligible compared to the time taken by the web request and database query. However, if we are making software for an embedded device or an application with real time capabilities, then the extra method calls and object creations might hurt. However it is difficult to conclude either way without running a profiler.

So I'd say... first create a good design and make it work. If performance is an issue, run a profiler on the application and fine tune those portions that are the biggest bottlenecks. If in the process, some design has to be sacrificed, so be it. But sacrifice design only and only if it is absolutely necessary, and there is no other option.




Resources:

  1. DRY Performance 


Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

And a few more (maybe)

While discussing goals of software design with other developers, a few more potentiall goals came up. They were, robustness, correctness, time to market, staying in tune with team capability, reusability, efficiency, and usability. After some analysis (in my opinion) only reusability passed the test of whether something is a goal of software design. I used a simple test - if we can use design principles like loose coupling, etc to enhance the candidate and if we (almost) always want it as an end result of software development, then the candidate passes the test for a software design goal.

So, as of now reusability defenitely is a design goal. We achieve it by following the DRY principle. Any code that needs to be called accross methods in a class should be factored into a seperate method in that class, and any code that needs to be called accross classes, should be factored into a seperate class. This is reusability from an object oriented design perspective, but it can be taken further by creating reusable components. For example if we are building a web application, in all likelihood the authentication code will be needed by other web applications as well. We make it reusable by creating an Authentication component, by packaging all authentication classes into the same package heirarchy and creating a facade class that can be used by client code. The facade class should ideally implement some standard authentication (or a well thought of API in case a stadard does not exist) API, to enable users to swap it with another authentication component.

Thats it about goals of software design. Do write back with your thoughts, perspectives, and queries. 



Note: This post was originally posted on my blog at http://www.adaptivelearningonline.net

Monday, October 09, 2006

Different aspects of software design

Yesterday while talking about goals of software design with some learning participants, we had an interesting discussion about the various aspects of software design. It is analogous to designing a housing complex. There is the macro level design of the buildings, gardens, club house, and jogging track. Then within every building we design the floor plan and the elevation. Each apartment has it's interiors designed separately. Beyond these designs, we also design the electrical systems, drainage systems, etc. The purpose of each design is different.

Similarly in an enterprise software system, we have various aspects of design. Some of them are:

  1. Enterprise and deployment design
  2. Component design
  3. Class design
  4. User Interface design

Each of these deals with a different aspect of the software system and has different goals.

Enterprise design  addresses high level components like naming and directory servers, application server, messaging server, databases, clusters, high level components and their deployment. The purpose of enterprise and deployment design is to create a deployment that fulfills the performance, budget, connectivity, and scalability needs of the enterprise. An enterprise designed must understand the capability of application servers, databases, clusters and other services such as naming and directory services. He must be able to balance requirement with capabilities and costs. An enterprise designer needs to figure out which components get deployed on which servers and how they interact with each other.

Component design usually addresses using and creating reusable components. While creating a software system, we often have to make build vs. buy decisions for certain reusable components. If we come across functionality that we feel can be reused across projects, then we factor out that functionality into a separate component. Each component should ideally have clear responsibilities which should be represented by the public interface of a facade class. This facade class will serve as the point of interaction for the rest of the software system.

Class design deals with flexibility, extensibility, and maintainability. It is all about identifying classes, assigning responsibilities, and understanding how the classes will interact with each other to fulfill their responsibilities. Here is where we deal with concepts like loose coupling, inheritance, polymorphism, and software design patterns. To learn more about object oriented class design, you can refer to the free (under development) course on object oriented analysis and design hosted on our site.

User Interface design addresses usability issues of a software system. Through usability design we ensure that the user interface is intuitive and easy to use. It should be easy and quick to do common tasks, and impossible to do things the user is not allowed to do. It should present information in a way that is easy to use.

All of these are various aspects of software design. Each has a specific goal and a process to achieve good design. 

Sunday, October 08, 2006

Should all learning professionals be blogging?

Recently Tony Karrer asked on the learning circuits blog: Should all learning professionals be blogging? He also encouraged people to comment by posting on their own blog, a concept that Stephen Downes thinks is a huge advance. If you have been following this blog, you will remember that I have been encouraging readers to post their perspectives on the course material in the learning section, on their own blogs, and informing me about the post.

Well, here is my response to the question.

What learning professionals should be doing is this:

  • Staying up the learning curve on technologies that affect them
  • Reflect on their learnings to gain a deeper understanding
  • Share these reflections with others to validate their ideas
  • Have conversations with other professionals to share their knowledge and learn from others
  • Manage the knowledge base of their reflections, resources, etc

Writing works wonders for reflecting on concepts. I cannot stress enough, how useful the process of writing is for reflection. Communication and conversations with peers can happen in a variety of ways: water cooler discussions, phone conversations, emails, forums, etc.

What is important is reflection and conversations, and blogging seem to bundle both in a very easy and effective way. People can reflect over a concept and write a blog post. But it doesn't end here. Conversations are spawned by readers who write a response on their own blogs and trackback to the original post, or by commenting and querying on the authors blog. With the possibility to integrate audio, animations, and slide shows, we have an even richer way to publish and communicate.

So, blogging is all about publishing, communicating, and creating an informal network of peers, and a community of reciprocal learning. That is why it is so important.

My conclusion: It is important to reflect and communicate, and at the moment blogging seems to be the best way to accomplish both. Till we have a better option, I'd say "Yes, all learning professionals should blog"

Perspectives from other learners/bloggers:

  1. Stephen Downes
  2. Geetha Krishnan
  3. Dave Lee 


Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net
Here are the comments from the original post

-----
COMMENT:
AUTHOR: Tarun Chandel
EMAIL:
URL: tarunchandel.blogspot.com
DATE: 10/19/2006 09:24:48 AM
Hello Parag sir,

First of all I must thank you for this site. It's a nice way to get to read about your thoughts. Blogging is a nice thing but has it's limitations. Blogging is essentially like a diary which is up for everyone to read. Blog is best place to express your views about something and other person can get an insight into your thoughts.
If we try to use blogging as a place where various people can come together to share and learn then it is not that great a medium.
For that kind of collaborative experience we need to have something which can help the users communicate with each other and as a group more effectively. A customized Social Networking site can be good solution, but again that will need a lot of work and nothing great is available off the shelf as of now.
I have also tried using blog for various different situations but it is not that great a solution. Blogs I find are very helpful in case you want to express your personal views on any topic.

COMMENT:
AUTHOR: Parag
DATE: 10/19/2006 12:15:01 PM
Social networking sites are good because they give a common platform to a community. But if you think about it the Internet is the common platform.

The biggest issue with social networking sites is that they form a closed community. Those who are not part of that community cannot participate. For example if you have your profile on Ryze then you cannot connect to those who have their profiles on LinkedIn.

Managing multiple accounts can be very tedious. Personal webpages, wikis, and blogs work wonders here, because they use the Internet as the medium. I can connect to you through your blog, without being a member of a community. This is very powerful, because it lets people connect and collaborate without the annoyance of signing up with a particular community.

Probably tools that can map and manage conversations accross multiple blogs will be very useful to view a conversation in entirety. Not very sure how it can be achieved though.

At the moment we can use blogs to establish conversations, disseminating information (product, etc), sharing perspectives, best practices, etc.

Forums work out better for solving specific queries.

Podcasts are also a very interesting medium. They are being used for learning, as well as a replacement for international conference calls in some companies. Podcasts work very well because they transcend time zones. People can listen to them when it is convinient and yet communicate on a common platform. Again that common platform can be a blog for that podcast.

Grassroots journalism is another important application that blogs are being used for.

I think we have probably just scrathed the surface for blogging applications. In time to come there will be many more creative uses of blogs.

Would like to know what you think.

--
Parag

COMMENT:
AUTHOR: Ranjan
EMAIL:
URL: http://ranjanjha.blogspot.com
DATE: 10/27/2006 02:26:40 PM
Hi Sir

I was following your and Tarun's discussion about blogging and I just wonder did we had this kind of discussionn while were in classroon :)

According to technorati.com a blog is created every 7 second, more than 70000 blogs are created in a month and presently there are more than 25 million blogs!

The porpuse of putting this stats is that people are using the internet to 'upload' contents which is a big change,the internet is becoming more collaborative in nature and blogging makes the nature of information 'open source'; blogging is the best example of 'open source journalism' as some of the breaking news are provided by bloggers rather than 'professionals'.

Learning professionals should be blogging as they get wider audiance and the discussion become more open. As you rightly said it helps in reflection, the amount of research work that is needed before putting up a post is high as your voice is being heard and commented upon by wider range of people.

I wonder if you can invite more people on this blog to write article, the blog will become more intresting. Maybe you can add some of them as memebers to this site and ecourage them to post articles, this way the audiance will get more people to lsiten to and comment.

Regards
Ranjan

COMMENT:
AUTHOR: Parag
DATE: 10/28/2006 09:51:00 AM
Hello Ranjan,
I agree, open discussions are very important to learning and generally broadening the perspective. Getting other people involved on this blog is a very good idea.

In fact I have been thinking to extend this initiative with a podcast station, that will focus on core software skills. I plan to invite several experienced people from the industry to share their knowledge on the podcast. Will post details on this blog as soon as I have thrashed out the details.

Thanks for the suggestions.

--
Parag