Skip to main content
added 78 characters in body
Source Link
Theraot
  • 9.2k
  • 2
  • 29
  • 36

Oh, by the way, that is all within the realm of Object Oriented Design. I've been assuming a language that favors the Java branch of Object Oriented Programming. Yet, that is not always the case. Know that the patterns work around what the language offers you, and thus you would use different patterns on different language. And while you can use OOD patterns in a language that is not intended for OOP, we can assume there are ways to go about it adapt better to those languages. For example, some languages let you have enum options that have attributes.

Oh, by the way, that is all within the realm of Object Oriented Design. I've been assuming a language that favors the Java branch of Object Oriented Programming. Yet, that is not always the case. Know that the patterns work around what the language offers you, and thus you would use different patterns on different language. And while you can use OOD patterns in a language that is not intended for OOP, we can assume there are ways to go about it adapt better to those languages.

Oh, by the way, that is all within the realm of Object Oriented Design. I've been assuming a language that favors the Java branch of Object Oriented Programming. Yet, that is not always the case. Know that the patterns work around what the language offers you, and thus you would use different patterns on different language. And while you can use OOD patterns in a language that is not intended for OOP, we can assume there are ways to go about it adapt better to those languages. For example, some languages let you have enum options that have attributes.

Source Link
Theraot
  • 9.2k
  • 2
  • 29
  • 36


Keep it simple

I understand this is likely a toy scenario. And perhaps there is a teacher passing judgement on some criteria of goodness of the design. However, the correct way to do this depends on the requirements, and toy scenarios often have loose requirements compared to the real scenarios.

For that case, I'd favor whatever is easier to extend and easier to understand, which, I believe, would be having multiple classes in this case. You can add more classes if you need them, without having to modify what is already there. Also I think a teacher would want to see you use inheritance. Although, empty classes is often considered a code smell.

There are, of course, more complex approaches that you might need depending on the situation, and I'll mention some of them and some criteria to pick in the nuanced answer blow. Why? Because I don't want to give the impression that there is a correct way to do it that always apply, nor want to dumb down the decision.

However, take this as a reminder to keep it simple. If you don't need an element in your design, don't have it. If you need to pick between equally likely approaches, pick the simple and easy to understand and to extend.


The nuanced answer

Systems need boundaries.

As designer/architect you need to identify/establish a boundary for the system. This is part of the definition of the scope of the project.

If you are, for example, trying to model reality (which is not always the case), you need to consider what things are relevant for the system, and what things aren't.

For example, if you are making an information system for a zoo, you may want to include on what part of the zoo they keep the animal. If you are not making a zoo, that is probably not relevant or doesn't make sense in the system at all.

For another example, if you are modeling street trafic, you might have some properties about the cars, such as their max speed and acceleration. If you are making an information system for a car repair shop, perhaps you are more interested in the repair history of the car, such as what parts have been replaced and so on. That would be out of the scope of the street trafic model.


How to pick between a class and attribute?

Consider, do different animals have different behavior? Is that relevant for the system? does the system treat different animals different?

If the answer is yes, then have a class for each animal. Otherwise treat it like an attribute/property.

For example, cars of different colors behave the same. We do not need to define custom classes for cars of each color, instead we have an attribute/property.

Let us say you have decided that it should be an attribute/property. Your next question is whether or not you can list all possible values during your design process. If you can, then an enum is good solution. Otherwise, consider having kind type for that.

For example you can have an "AnimalSpecies" type that you can initialize with a name, and each animal object would have an "Species" attribute/property of type "AnimalSpecies".


There are other patterns and architectures.

Sometimes a system treats different values of an attribute/property differently, but it does not justify making a new class for each value. In particular, if you have an enum, there could be another part of the system that makes a decision based on the value of that enum. For example, a part of the system shows to user a different picture depending on the kind of animal... Or another part of the system picks different food for different kind of animal, etc...

Here I'd remind you the Single Responsibility Principle. You may have different behavior that depends on the value of that attribute, but they can be different responsibilities, and would belong in different classes.

You can consider using what I called kind type for that, that is, the "AnimalSpecies" can hold the pictures you show, of their food for each case. You might even have to use a different types that have different behavior for the "Species" attribute. See also Strategy pattern.


Oh, by the way, that is all within the realm of Object Oriented Design. I've been assuming a language that favors the Java branch of Object Oriented Programming. Yet, that is not always the case. Know that the patterns work around what the language offers you, and thus you would use different patterns on different language. And while you can use OOD patterns in a language that is not intended for OOP, we can assume there are ways to go about it adapt better to those languages.


Sometimes you need to split your solution into subsystems, each with their own scope and boundary. For example, what picture to show is a presentation concern, but what is their food is not. In that case, either having the enum, or having the "AnimalSpecies" be a simple value that can be passed across boundaries is better. Each subsystem can then pick strategies to handle each case based on that value.


Design is iterative.

Finally I want to say that you do not need to nail the design on the first attempt. Take it as an interactive process. If it is hard to accommodate the requirements in the design you have, refactor it, or consider a different approach. Similarly, new or changing requirements are likely to require changes in your design.

I have given you some considerations that I hope can help you take a decision in a real scenario. However, start with a simple design. If you don't need an element in your design, don't have it. When new requirements come, you will know how to extend your system. And if that requires a refactor, then so be it.

And to reiterate, keep it simple.