modified abstract factory