Abstract factory + full example