add factory pattern with unit tests