added abstract factory pattern