How to design objects?

Thus, there are many ways to structure objects (here we are talking about OOP). When asked, I will use the classic OOP โ€œcarโ€ example. Basically, how do I know when to make a car an object or a car wheel an object, when both program structures reach the goal?

How to classify and classify parts of an object to determine whether they are best suited as simple attributes or variables of the object, or should they really be the object itself?

+6
oop
source share
7 answers

Well, the first thing you need to understand is OOAD (Object Oriented Analysis and Design) - a tool, not a means to an end. What you get from this process is a model, not a true representation of what you are modeling. This model makes certain assumptions. The goal of this model is to solve the problem you have.

So how do you know how to design objects? How do you know if you did it right? Towards the end of the job: does your problem solve?

So, for the Car example, in some models the number of cars may simply be an integer, for example, car traffic through the intersection of the traffic model. In such a model, you rarely care about the make, model or design of cars, just about quantity. You may care about the type of vehicle to the extent that it is a truck or a car (for example). Do you model this as a vehicle object with a type of car or truck? Or just split carCount and truckCount?

Short answer: which one works best.

A normal test of whether an object is or not, does it have behavior? Remember that ultimately objects = data + behavior.

So you can say that cars have the following condition:

  • wheels

  • Suspension height;
  • Left or right drive;
  • Colour
  • Width;
  • Weight
  • Length;
  • Height;
  • doors;

  • Does he have a sunroof,
  • Does it have a stereo, CD player, MP3 player and / or satnav;
  • Tank size;
  • Number of cylinders;
  • turbocharging and / or fuel injection;

  • Maximum torque;
  • Maximum braking power;
  • etc.

Most likely, you will only care about a small subset: select everything that matters. A racing game may include more detailed information about the wheels, for example, how hot they are, how worn out they are, the width and type of tread, and so on. In this case, the Wheel object can be called the totality of this state (but small behavior), since the car has several wheels, and the wheels are interchangeable.

Thus, a second point arises around the objects: the object may exist due to the relationship, so the object is a complete set of data. Thus, the wheel may have patronage, width, temperature, and so on. You cannot share this and say that the car has a tread, but there is no wheel width, so it makes sense for the Wheel to be an object, since the wheel in it is completely interchangeable.

But then again, does that make sense for what he's doing? This is a key question.

+6
source share

Do not start by classifying things - it seems that people are too eager to start creating inheritance hierarchies.

write down a list of specific specific scenarios - what your application will do, step by step. An object model is only useful when it does what you need to do this, so start working with scripts to see what common objects and behavior you can shake out of each.

identify the "roles" in your scripts - not necessarily the names of real classes - just the vague "roles" that appear when you think in specific scenarios how your software will work. These roles can subsequently become classes, interfaces, abstract classes - no matter what you need - at the beginning they are just placeholders to do the type of work.

Define what each role does. The key contains a bunch of named roles that define the things that objects will do. A tins is a distraction of the many things that each of them can do - they can do all this or collect a bunch of other objects to do the work, or they can coordinate the work ... it depends on your scenarios.

The most important thing in OOD / OOP is the OBJECTS OF THINGS - not that inside them is what they do.

Do not think about inheritance at an early stage , because it will bind you to complex hierarchies and make you think in terms of SQL-oriented programming rather than object-oriented programming. Inheritance is just one way to share common code. There are many other ways: delegation, mixes, prototype programming ...

Here are some guidelines I came up with to help with this:

What should be on the checklist to help someone develop good OO software?

+5
source share

There are some good answers here, but maybe more than what you were looking for. To briefly review your specific questions:

  • How do you know when to make a car an object or a car wheel an object when both structures of the program reach the goal?

    If you need to distinguish one instance from another, you need an object. The key distinction of an object: it has an identity.

    Extending this answer a bit to classes, when the behavior and / or properties of two similar objects diverge, you need a new class.

    So, if you are modeling a traffic simulation that takes into account wheels, a vehicle class with the NumberOfWheels property may be sufficient. If you are simulating a racing simulation with detailed physics of road surface and torque, each wheel should probably be an independent object.

  • How to classify and classify parts of an object to determine whether they are best suited as simple attributes or variables of the object, or if they really should be the object itself?

    Key differences are identification and behavior. A part with a unique existence is an object. The autonomous behavior part requires its own class.

    For example, if you create a very simple car simulation, then NumberOfPassengers and DamageResistance may be sufficient properties of the generic Vehicle class. That would be enough to tell you if the car was combined and the passengers survived. If your simulation is much more detailed, perhaps you want to know how far each passenger has a head-on collision, then you will need a passenger class and separate passenger objects in each car.

+2
source share

I like Wirfs-Brock 's Responsibility Management (RDD) and also recommend this updated (free paper) Responsibility-Based Approach , Alistair Cockburn.

In more than 15 years of developing OO, whenever I feel like I'm lost in software architecture, returning to the basics of RDD always helps me clarify what software should do and how.

If you like a validation-based approach, this article shows how to relate RDD to mock objects and tests.

+1
source share

Attributes or variables are often the "basic" types of language. The question is that you can reasonably disengage.

For example, you can reduce Wheel to descriptors consisting of basic types, such as integers, floating point values, and strings that represent the characteristic attributes of any wheel: numberOfTreads , diameter , width , recommendedPressure , brand . These attributes can be expressed as the base types for creating the Wheel object.

Can you combine some of these attributes into a more abstract design that you can reuse regardless of Wheel ? I think so. Perhaps create a Dimensions object with the diameter and width attributes. Then your Wheel has an associated instance of the Dimensions object instead of diameter and width . But you might consider using this Dimensions object with other objects, which may not necessarily be Wheel instances.

Lift the list, you can reduce the Car , which will consist of basic types, but also other objects, such as Wheel objects. It is wise to do this because other motorized and non-motorized vehicles (such as Bicycle ) also contain Wheel instances.

Testing Wheel and Dimensions allows you to reuse these types of objects in different contexts that you cannot initially consider. It makes your life a little easier because you have less code to rewrite, theoretically.

If you can create a hierarchy of objects, to the point where the deepest object of the lowest level consists of only a few basic types, this is probably a good place to start.

0
source share

If it is true that "both program structures have achieved the goal" equally well, then it does not matter what you choose.

If, however, the program does not have a single fixed "target", but it will increase significantly during its life cycle, then select one of them at the moment and refactor as necessary, as further modifications require. We call this โ€œsoftwareโ€ for some reason.

0
source share

Develop your classes from the bottom up.

1) The boundaries and semantics of classes depend on the context. As long as you have no context, you have nothing. (You may not even have a car in your example). The context is defined by the user's story (or use case).

2) Throw all the state and behavior offered by this context into one class (you can call it after the userโ€™s history, if you want).

3) Use systematic Refactoring to divide this class into separate classes. During refactoring, use existing classes as reusability options.

When you're done, you will have a set of well-defined classes that are enough to meet the needs of a given user story (and user stories that were before).

0
source share

All Articles