DRY up campaign components into abstract class