Вопрос

Is there a name or a particular rule for objects that contain objects that contain... and so on. I'm working with a complex system that often has objects running 5-10 layers deep. One reason I'm hearing for why this is done is to pass a lot of data from server to client all at once, is there a better way to do this?

Edit: It seems that it is a combination of a few anti patterns. The Domain model should be cleaned up, and the following antipatterns are the smells: Train Wreck Pattern, and Everything but the kitchen-sink map

Это было полезно?

Решение 2

This looks like a domain model gone sour (not an antipattern name, BTW :) It stems from the illusion that there is such a thing as a well-defined domain model. In reality, there are some aspects of the problem domain that can be elegantly modelled, but at the finer level of detail there are exceptions upon exceptions and special cases upon special cases, each specific to a single service method, that destroy this elegance.

The appearance of many nested objects is often the result of a continuous process of "grinding down" the domain model to ever finer granularities, in the hope that every instance variable may be reused in different contexts. There is a breaking point where the dogmatic imperative to reuse each and every domain attribute just stops making sense.

My way out of this is to stop trying to create a one-size-fits-all domain model and use objects specifically designed for each service call. These objects may rely upon some of the well-defined domain objects, but add any specific information separately and in a way that doesn't interfere with other service calls.

Другие советы

I don't know a name for this kind of object tree. But a well known anti-pattern is the Train Wreck Pattern which occurs when code uses excessive method chaining.

objA.getChildB().getChildC().getChildD()....getChildZ().performSomeAction();

It is a good rule of thumb to wrap all of

.getChildC().getChildD()....getChildZ().performSomeAction();

into an method on

objA.getChildB()

Let's call this method performSomeActionDeepDownTheObjectTree().

The term is "object orientation" wherein you decompose large complex problems into smaller problems by defining classes of objects each of which encapsulates a small part of the problem. The way objects interact is by message passing and objects find other objects to pass messages to by starting with the objects they contain.

The larger and more complex the problem, the more work you have to do to decompose it into manageable pieces, so the more layers of objects you get. Sometimes small simple problems are decomposed badly into large numbers of objects, but that doesn't make object orientation itself an anti-pattern.


the main problem is simply that the data objects grow too large through nesting as well as including irrelevent data. Example: You're sorting birds and rather than a simple bird object you receive an object bird, containing feathers, beak, possibleParasites, air, possibleHousesNestsCanBeIn, and foodTypes, food types contains fruit, insects, worms, seeds, seeds contains oak, elm, thistle, possibleAnimalsThatCanEatSeeds etc etc –

The Everything but the kitchen-sink map anti-pattern is probably the closest fit.

Given a complex process with many complex rules, everything (business logic, related and unrelated procedures, etc) is shoved into the map.

The best way to solve this is with a filtering operation where you specify a strongly typed interface like interface BirdList extends Iterable<Bird> {} and the query system provides an implementation of that backed by just enough data to support that interface.

Your API could provide a number of different interfaces like BirdList and BirdFeedingHabitMap, BirdNestingHabitMap, etc. Clients can come up with a list of interfaces they need and the query system analyzes them, fetches the data, and uses proxy classes to assemble an implementation class that exposes the query results in a type-safe way.

Objects containing objects containing… etc

is called a list and perfectly fine ;)

But you are right, long sequences of method calls is all but fine and a clean code smell called inappropriate intimacy.

Inappropriate intimacy can increase coupling, decrease cohesion, goes against the law of demeter and the rule tell, don't ask.

References: If you look up those terms, you will find a fantastillion many answers. Particularly good ones are Cohesion and Coupling and the book Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top