Aggregate are cluster of objects that change together and are treated as a unit of transaction. Classic example of aggregate would be the Order class. Order contains Line-items. Line-items cannot exist and have no meaning without an Order. But, more importantly, Order and Order line-item must change together in an ACID fashion – either both change or none. in other words, Order and Order Line-items must always be consistent.
There is another kind of consistency that Domain Driven Design talks about that often creeps out a lot of developers, called the Eventual Consistency. With Eventual Consistency, the states between parts of the model are allowed to be in a temporary inconsistent state. The acceptable duration before which they must be brought to a consistent state is what is called the business Service Level Agreement (SLA). Talk to your business SMEs, you would be surprised to find out how many things in your model can be made eventually consistent.
In an aggregate, one of the objects (entities in DDD terms) becomes what is called the Root for the Aggregate. Aggregate Roots are the door-way to the aggregates. All objects in an aggregate must be accessed through the aggregate root. This ensures that loading, state-change and persisting of the entire aggregate happens as a unit and hence the transactional consistency is never compromised.
Another advantage of having a single point-of-access to all other objects in the aggregate is that the Aggregate Roots can internally access the states of different child object and decide if the requested state change will result in the valid state of the aggregate or not. Hence, they become a natural host for many if not most business rules related to the aggregates.
Even if you do not intend to use full-blown Domain Driven Design, identifying the portions of your model or object graph that change together and treating them as a unit of transaction can go a long way in taming the complexity of you application.