add abstract_factory pattern