0

I'm trying to learn proper object-oriented design, with class relations and avoiding anemic domain models[1]. I'm creating an application to store and retrieve information about "cyberattacks". There are five relevant classes to this question:

  • Directory: the class representing the collection of the data indicated below
  • Group: a group of attackers known to be related to each other
  • Hacker: a person who makes an attack
  • Attack: a hacking attack, including information such as severity and cost to repair the damage
  • Type: attacks are classified into these types, i.e. denial of service, information leak and so on. These types are entered by the user when they add an attack.

The kinds of questions users of the application will ask are:

  • Which Attacks have been performed by a specific Hacker? The response includes information about the damage of each Attack, as well as which Type it has.

  • For a specific Group, which attacks have been made? By whom, and which was caused the highest damage cost?

  • For a specific Type, which attacks are made? Who did them? What is the total damage cost?

The naive way to solve this would include a lot of circular dependencies between these classes (i.e. a Hacker has Attacks, but Attacks also have Hackers, and a Type has Attacks, but an Attack also has a Type, and so on.) As circular dependencies are unwanted, how would I solve this with proper OO design?

  • 1
    I don't see any behavior in your description, so "proper OO design" doesn't really apply. It is, however, an example of the sorts of relationships (including circular references) that relational databases handle very well. – kdgregory Jan 8 '17 at 14:22
  • 1
    This isn't a very OOP problem. In the real world, the best solution would be to put all your data into a relational database and write an SQL query for each use case. There are well-established patterns to represent the database in your domain model, e.g. through the Active Record pattern (each DB row is represented as an object and does SQL queries in the background to return related data) or the Repository Pattern (each DB table is represented as an object that performs queries on the table and returns the results as objects) – amon Jan 8 '17 at 15:15
  • 2
    Don't assume that educators create good examples. There's a plethora of "object zoos" as counter-evidence. – kdgregory Jan 8 '17 at 15:23
  • 2
    I think it's also worth noting that Martin Fowler, who I believe coined the term "anemic domain model" also said (in this post) "Indeed in many cases you shouldn't think of building a behavior-rich domain model at all[.]" (he then links to a post on an alternative). – kdgregory Jan 8 '17 at 15:28
  • 2
    You are describing data as classes, but you should be describing behaviors as classes. You would have one or more "report" classes, which implement your use cases. The data structure should just go in a DB and does not necessarily need to exist as is in classes at all. – Sklivvz Jan 8 '17 at 22:07
1

When objects have relationships to each other it is important to define what the relationships are.

When you say "The naive way to solve this would include a lot of circular dependencies between these classes (i.e. a Hacker has Attacks, but Attacks also have Hackers, and a Type has Attacks, but an Attack also has a Type, and so on.) As circular dependencies are unwanted, how would I solve this with proper OO design?"

you use the word 'has' (or 'have') for both relationships but don't define what that really means. I suspect that it would be more precise to say:

Attack have many hackers
Hackers belong to an Attack (foreign key attack_id)

A given Attack Types has many Attacks
Attack have an Attack type (foreign key attack_type_id)

And thus these are not circular references, just one-to-many relationships.

0

My first reaction is to agree with the commenters. But if we must pull data into an application how would we structure that? This is not an attempt to emulate a RDBMS engine; I'm going to ignore indexing, normalization, and relational algebra generally.


Meta Data

To help avoid circular references design a metadata class for each class - Hacker, Attack, etc.

The idea is to have some information (that defines "equals" for example) while not instantiating a reference chain, circular or not, of detail objects. And not wasting time, memory, etc. when we don't know yet which details we will need.


Directory

I see this as an abstraction for a given specific problem. It is context that will inform what objects we start with and what parts of a relational chain are relevant. Naive circular references can be avoided.

Further, coding should consciously be done to avoid closed loop reference chains. Beyond context, yet to be done design analysis may reveal useful objects as sub-parts of the presumed data classes: i.e. Hacker, Attack, etc.


All the other classes

Design each class to include all appropriate properties for related objects. So a Hacker has a collection of Attacks.

Thoughtful analysis may reveal other component classes that may be helpful and essentially is a dead end in a relationship chain. The idea of a MetaData class is an example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.