General Criteria for Distributed Software Design