add abstract factory