Tuesday, December 09, 2008

Zoetrope, new concept aimed at providing access to temporal web content. It lest people see how things (any) have evolved over a period of time. One useful thing that can be done using Zoetrope is to spot the best time to buy books on Amazon :-)

Zoetrope in action

Tuesday, November 18, 2008

Really cool stuff

Usability is still an issue with PCs. There are smart people (who works around an issue instead of simply nodding in disgust) out in the world ... proof? check this video



Tuesday, September 02, 2008

Google Chrome

Wish, it comes out soon :-)

http://blogoscoped.com/archive/2008-09-01-n47.html

http://blogoscoped.com/google-chrome/

Un named structures and VS8

With two un-named structures , the linker on Windows has thrown the following error

unnamed_struct.obj : fatal error LNK1179: invalid or corrupt file:
duplicate COMDAT '??1@@QAE@XZ'
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual
Studio 8\VC\BIN\link.EXE"' : return code '0x49b'
Stop.

The above is observed even with the varying number of struct members.

Known Issue: If two unnamed structs both declare a method with the same signature
and both are referenced, the compiler generates the same signature for both methods.
The linker then flags the .obj file as invalid due to duplicate COMDAT records
(More about this issue here)

The solution to this problem is, not to use more than one un-named structures

Sunday, July 27, 2008

Good Stack Overflow Podcasts

These are worth an ear...

Talks about who can be a good Manager, time management techniques, how to benefit out of good code review process, and discussion around attending/preparing for Interviews..

Podcast 15: Jeff Atwood and Joel Spolsky

Saturday, July 19, 2008

Wednesday, June 18, 2008

Beautiful Software

Here is a good article that compares construction work to building software systems. Though it's quite an old article written by Charles Connell, is very much relevant to our times

The key points are
  • Don't let customers compromise on the quality of the software
  • Write small, simple, readable code (even for the complex issues)
  • Strive to provide only the necessary functionality (bang for the buck for both users and developers)
  • Ensure that software works in a co-operative manner (with others resources of the system)
  • Ensure that external functionality of a software can easily be mapped to the code (reduces maintenance or enhancement costs)

Friday, June 13, 2008

Good Tech Videos

NWCPP: Machine Architecture: Things Your Programming Language Neve - Herb Sutter

Wednesday, May 21, 2008

Liskov Substitution Principle (LSP) and Design By Contract (DBC)

Adhering to OCP requires employing abstraction and inheritance. The key concern LSP promises to address is the quality of the inheritance (What? Quality of inheritance? Yes). If inheritance is not applied correctly i.e if any inheritance violates LSP, ends up violating OCP too.

In OO programming IS-A should be thought in terms of object's behavior. Following example should help us understanding it better.

Is rectangle A square? Mathematically yes when width is same as its height. So lets device and interface to work with squares and rectangles.

class RectangualShape {
public:
virtual void SetWidth( int w ) = 0;
virtual void SerHeight( int h ) = 0;
virtual int Area() = 0;
};

class Rectangle: public RectangularShape {
public:
virtual void SetWidth( int w ) { width = w; }
virtual void SetHeight( int h ) { height = h; }
virtual int Area() { return width * height; }

private:
int width;
int height;
};

class Square: public RectangularShape {
public:
virtual void SetWidth( int w ) { side = w; }
virtual void SetHeight( int h ) { side = h; }
virtual int Area() { return side* side; }

private:
int side;
};


int main()
{
int w= 1;
int h = 2;
RectangualShape *rect = new Rectangle();

rect->SetWidth( w );
rect->SetHeight( h );
assert( (w * h) == rect->Area() );

RectangualShape *sqr = new Square();

sqr->SetWidth( w );
sqr->SetHeight( h );
assert( (w * h) == sqr->Area() ); // BINGO, assertion fails

return 0;
}

Why did the assertion fail for square shape? Because a square is behaviorally different from a rectangle (except in one instance). So misusing IS-A relationship results in inheritance that violates both LSP and OCP.

The above example emphasizes the fact that derived classes should behave as advertised in the base class.

The Principle

Inheritance should ensure that any property proved about super type objects also holds for sub type objects -B. Liskov (87)

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it - R. Martin (96)

A few key things to note about using interface are

  • Its illegal for a derived class to override a base class method with NOP (no operation)
  • Establish and document the interface contracts (DBC)
  • Any inheritance that violates LSP also violates OCP

When inheritance is involved, users of an interface (abstract base class) need not care for how a derived class behaves. Its expected that derived classes also keeps the promise made by the abstract base class. Then how does the users know what an interface is promising? Well by looking at the class, or otherwise through documentation.

Design By Contract (DBC): Its nothing but advertized behavior of an object

  • Advertized Requirements (Preconditons), i.e callers should not assume anything and should always pass valid arguments
  • Advertized Promises (Postconditons), i.e expected behavior or results

To keep the interface promise: When redefining a method in a derived class, you may only replace its precondition by a weaker one and its postcondition by a stronger one - B. Mayer (88)

Key points of DBC

  • Derived class services should require no more and promise no less
  • Document pre and post conditions
  • Because of preconditions, DBC says methods need not do any validations on input arguments
  • Invariants can be used effectively to see whether any derived class violates the base class behavior or not


class RectangualShape {
public:
/**
* Precond: Positive integer < 100
* Postcond: void
*/

// w should have been unsigned, precond should help us
virtual void SetWidth( int w ) = 0;

/**
* Precond: Positive integer < 100
* Postcond: void
*/
virtual void SerHeight( int h ) = 0;

/**
* Precond: void
* Postcond: w * h
*/
virtual int Area() = 0;
};

References:

Liskov Substitution Principle - PDF
Design Principles and Design Patterns - PDF
Principles of Object Oriented Design - PPT
Advanced Principles of OO Class Design - PPT

Thursday, May 15, 2008

C++ tidbit - virtual functions and default arguments

Virtual functions are bound dynamically where as default arguments are bound statically

class Base {
public:
virtual void func( int x = 10 ) {
_x = x;
std::cout << _x;
};

private:
int _x;
};

class Derived: public Base {
public:
virtual void func( int x = 20 ) {
_x = x;
std::cout << _x;
};

private:
int _x;
};

int main()
{
Base *b = new Base();
std::cout << "Default Value in Base: ";
b->func();
std::cout << std::endl;

Base *d = new Derived();
std::cout << "Default Value in Derived: ";
d->func();
std::cout << std::endl;

return 0;
}

Output:

Default Value in Base: 10
Default Value in Derived: 10

Default arguments of virtual methods in the base gets statically bound (in our case Base::func() ), hence never override the default values in derived virtual methods, doing so might confuse us with derived object's default behavior.

Sunday, April 27, 2008

Single Responsibility Principle (SRP)

Principle: A class (object) should have one and only one, reason to change

SRP says, a class (object) should emit a single behavior (collection of methods resulting in that one behavior). Any changes to the object's behavior should only be the reason to make changes to its corresponding class. Adhering to SRP should result in modular, flexible and cohesive interfaces.

Here is an example that violates SRP

class Payroll {
public:
void ComputePaySlip( const std::string & emp_id );
void ShowPaySlip( const std::string & emp_id );

...
};

There are two tasks in Payroll class , pay computation and pay slip presentation. Potentially these two jobs can be separated out each going into its own class.

The computation part calculates the monthly pay based on number of working hours, special incentives if any, any deductions and tax to withhold etc. If the taxation rules changes, the behavior of Payroll needs to be modified (for a valid reason) but it might unknowingly disrupt the functionality (behavior) of the pay slip presentation part as both were sharing the same object data.

In similar manner, any change in requirements to modify the presentation logic might affect the pay computation part due to the implicit dependency (being part of the same object).

It might be a good idea to break the class into two as the current class seems to emit two potentially different behaviors. Decoupling the behaviors helps handling behavior change without worrying about potentially damaging the other (doesn't it sounds better dependency management?).

SRP might be very hard to implement, it requires good ability in judging what should be considered a single behavior (demarcating or separating behaviors is a complex job :-), but results would be plenty ).

References

SRP (objectmentor)
Advanced Principles of OO Class Design - PPT
Cohesion - SRP
SRP (wikipedia)
SRP (DDJ)


Previous Topic:

Open Closed Principle

Friday, April 25, 2008

Open Closed Principle (OCP)

Lets see a simple and elegant piece of code (read input from keyboard and write the contents to a file)

void Copy()
{
int c;

while( ( c = ReadKeyboard() ) != EOF )
{
WriteToFile(c);
}
}

It is/was considered elegant because each module hides lot of details from the user (of copy). One doesn't need to bother about how the keyboard works or what kind of keyboard it is etc, so is the same with writing to files.

The only issue with this piece of code is lack re usability. Ex: read from keyboard and write to a printer instead of a file (its rigid and immobile).

The interface Copy need to be modified to accommodate new requirement which potentially might break the existing functionality, that’s exactly what OCP attempts to avoid/attack.

Following is a modified code to accommodate new requirement (ability to write to a printer)

enum OutputDev { printer, file };

void Copy( OutputDev dev )
{
int c;

while( ( c = ReadKeyboard() ) != EOF )
{
if( dev == printer )
WriteToPrinter(c);
else
WriteToFile(c);
}
}

Let see what OCP says

A module (C++ entity) should be open for extension and closed for modifications --R. Martin (96)
OR
Modules should be written so they can be extended without requiring them to be modified --B. Mayer (88)

OCP says that, adding new types of a behavior should not happen at the cost of potentially modifying the existing behavior (modifications might introduce bugs).

The whole idea is to add new types of behavior by extending rather by modifying the current behavior so that new additions can guarantee no dents to current behavior.

An interface/public method defines the behavior of an object. Abstraction is a key concept which helps writing OCP compliant interfaces. C++'s polymorphism (static and dynamic) helps extending behavior to new types.

OCP only talks about adding/extending the behavior and not about modifying the original behavior itself . If there are any logical flaws in the existing code, they need to be fixed.

OCP adhering solution looks as below

// abstract reader interface
class ReaderAbstract{
public:
virtual int Read( ) = 0;
};

// abstract writer interface

class WriterAbstract{
public:
virtual void Write( int c ) = 0;
}

class SrcKeyboard: public ReaderAbstract {
public:
int Read()
{
// read a character from keyboard
}
};

class SrcFile: public ReaderAbstract {
public:
int Read()
{
// read a character from file
}
};

class TrgtFile: public WriterAbstract {
public:
void Write( int c )
{
// write a character to file
}
};

class TrgtPrinter: public WriterAbstract {
public:
void Write( int c )
{
// write a character to printer
}
};


void Copy ReaderAbstract & src, WriterAbstract & trgt )
{
int c;

while( ( c = src.Read() ) ! = EOF )
trgt.Write( c );
}

Because the abstract interface allowed us easily adding new type of source and target without modifying the current code, we can say that our design is closed against modifications.

But it may not always be possible to close a design w.r.t potential modifications. OCP gives a breather here in form of strategic closure (partial OCP).

Strategic closure says that if full OCP is not possible, identify areas of an interface which can't be closed 100% against modifications, minimize its scope and document the same . Domain knowledge, design experience comes handy in figuring out where and how to apply strategic closure .

OCP Heuristics

  • Never make data members public as they might result in potential tight dependency in form of derived classes (if they are playing with the base public data members)
  • Global variables are dangerous (same as public data members)
  • RTTI, switch statements could be dangerous (mostly they work with types and adding new type might require changes to the code to accommodate the new types)
  • Based on circumstances and need basis, exceptions apply to OCP too (For example: globals are the only option to share vital information etc). Be very cautious before thinking of taking an exception from OCP


References

Design Principles and Design Patterns - PDF
The Open Closed Principle - PDF
The Open Close Principle - one more
OCP (DDJ)
Open/Closed Principle - wikipedia
The Open Closed Principle - Doodle Project
Principles of Object Oriented Design - PPT
Advanced Principles of OO Class Design - PPT


Previous Topic:

OO Design principles, an Intro

Thursday, April 17, 2008

Assorted OOD Principles - Introduction

Recently I have presented a tech talk to my team on assorted object oriented design principles (in C++). Here is an attempt to reproduce it in a better shape (my apologies to the concerned, if due acknowledgments were missing).

Issue: Software has behavior; it can suffer from aging and starts emitting smells

Aim: Control the direction of Software's behavior (i.e make it behave as intended and not the other way)

Our job is to get to know and benefit from well known, widely used design principles (we can find counter arguments too).

These principles are expected to help us

  • keeping the software correct, simple, stable, reusable, extendable …
  • reducing the learning curve for new comers, thereby saving $ for the company
  • feel proud thyself for delivering a great piece of software

Covered principles

  • Open Closed Principle (OCP)
  • Single Responsibility Principle (SRP)
  • Liskov Substitution Principle (LSP)
  • Dependency Inversion Principle (DIP)
  • Interface Segregation Principle (ISP)
  • Law of Demeter of Methods (LoD)

What goes wrong with Software?

  • People
    • A piece of code is the reflection of a person/team/organization
    • Any piece of software reflects the organizational structure that produced it (Melvin Conway)
  • Changing requirements (key cause)
    • Either we fix things or add behavior (call it enhancements)
    • Not all systems are designed/modified with further change in requirements in mind
  • Poor dependency management (very crucial design aspect)

As a result, Software starts emitting smells

  • Rigidity: making simple changes becomes hard, re usability decreases
  • Fragility: trivial changes cause the system to break in strangest places
  • Immobility: changes require major re-factor rather constant minor (simple) modifications/enhancing
  • Viscosity: doing things right becomes hard hence people start hacking (which may not preserve the design)
    • Viscosity of environment (confine changes to avoid tedious processes)
    • Viscosity of Design (choosing a simple hack over complex but correct solution, breaks the design)
In short: Aging code looks complex and un manageable (or simply call it LEGACY)

Friday, March 21, 2008

Perl & $?

Following should give us the correct error code.

$rslt = $? >> 8;

Then Windows app (command line) can exit with any value (can see using %ERRORLEVEL%).
Is is fair to expect a correct error code post $? >> 8 on Windows?

The answer doesn't seem to agree because Perl's system() API uses one byte to hold the exit status.

My application exits with error codes greater than 255. I have used the following hack to get correct error code on windows

$expected_err_code = 501;
$modified_expected_err_code = 501 % 256; // re-map to: - 0 - 255
$rslt = $? >> 8;

if( $rslt == $modified_expected_err_code ) {
print "Its OK";
}

It looks like the perl module IPC::System::Simple supports 32 bit exit status.