add abstract factory pattern