OOP: When is it an object?

2019-03-08 11:16发布

I'm trying to understand object orientation. I understand it a little bit of course, but sometimes I'm not 100% clear. How do you decide what should be turned into an object (small object part of another big whole object) or what is not worth being an object, or maybe it should be just a property of that big whole object?

For a door, I guess the door knob should be an independent object, but should that part in the middle where you insert the key also be an independent object or what? This is a simple example so I can explain my confusion. You can use your example if it helps you make your point better.

I was thinking that if maybe I'm going to use it multiple times, I should make it an object. This I think is a practical way to resolve this problem, do you agree?

Thanks

20条回答
甜甜的少女心
2楼-- · 2019-03-08 11:29

As always, the answer is unfortunatly: it depends...

At the beginning, you have some sort of environment and you want to create a model for it. But you would not model every thing, you'll concentrate on the important things. That's why I started with: it depends. It depends on what details you need to accomplish the task.

Take the car and it's wheels - if you model a city and want some traffic, you may create a 'Car' class with the attribute 'numberOfWheels'. But if you design cars, then you most likely want to create a class 'Wheel' aswell and add four of those to the 'Car' class.

Rule of a thumb:

  1. if that, what you're thinking about, has more then one attribute, define a class
  2. if that, what you're thinking about, has some behavior, define a class
  3. if that, what you're thinking about, may grow or be extended, define a class
  4. if that, what you're thinking about, has to be sortable, comparable, define a class
  5. if you're unsure, define a class ;)

Edit

Because you emphasized the 'multiple usage' aspect: I don't think that this is an aspect for a decision whether to use a class or not. Think of a simple counter, an integer value in a for loop. You'll use this concept hundreds of times but I bet you'll never think of wrapping this poor little int into a 'Counter' class - just because you use the 'concept of a counter' multiple times.

查看更多
唯我独甜
3楼-- · 2019-03-08 11:29

Everything can be made into an object.

IMO, the answer to your question is the question - Is the behaviour of the key-hole necessary for my model of the door to be an accurate representation?

When the answer to the above is in the affirmative, go ahead and incorporate it. When the answer to the same question is in the negative, then I'd choose not to.

查看更多
手持菜刀,她持情操
4楼-- · 2019-03-08 11:32

There is theory and then there is practice... and then there is you as a software engineer trying to balance them both.

In theory you should make objects pretty much everything until you fall down to the smallest possible elements, the primitive types (boolean, string, integer etc). Well.. it is rather simplistic but with this one rarely goes wrong...

that is...

until you actually get to create (that is code the classes) the thing.

On the practical end of the spectrum you can define all in one big class and be done with it... that is... until you have to define subtle change in behavior (outside door, garage door, dog door etc).

My approach is to usually start with the one big class (ugly but it's fast to code and I can get a working prototype faster). Then if I ever need to define ajustments or new behaviour or reuse some part of the whole then I create the smalle element and refactor the big one to use the smaller one instead of defining it's own attributes.

For example. I code the door class, and from there I can create (instantiate) as many door as I want but they are all the same and behave the same. Now I realize that I need to also define windows that swivel around hinges... wait a minute... the door`s got hinges also. This is where I create a hinge class that can be used by both Door and Window and remove whatever way I had before to define a hinge in the door class. Then continue working until I encounter a situation where I can reuse some parts across multiple objects (the handle, the frame, etc).

  • Never drill down the object until you have to but...
  • Never duplicate code that can be reused.

With this rule of thumb I can get the code fast and usually it converges to a level of granularity that is sufficient for the needs at hand.

Then with experience you get to have a fair idea of on deep you want your objects granularity without having to constantly re-factoring your objects which is time consuming. However I found that the re-factoring is time consuming but never as much as designing the thing all the way down right from start. Re-factoring is almost inevitable, as such better to start re-factoring early and often.

anyways... my two cent, I hope it helps.

查看更多
祖国的老花朵
5楼-- · 2019-03-08 11:32

Everything is an object. Sometimes you just use a primitive variable (int) to represent an object, and sometimes you create a data structure (struct/class). And naturally, some objects are parts of other objects.

So, yes, if you have to do in your code something with that part in the middle where you insert the key, it should also be an object in your code. It may be represented just by string Keyhole and may be represented by a class Keyhole, it may be an independent object and may be a part of the class DoorKnob - but anyway it will be an object.

In order to decide, whether an object should be independent, or should it be a part of a bigger object, you can just ask: Is it needed in the context outside the bigger object, or is it just a part of the bigger object's implementation.

查看更多
做自己的国王
6楼-- · 2019-03-08 11:33

You should also think about how many of the sub-objects you need. A door has one handle not four or five and not a list of handles. Also do the sub-objects have properties of their own? Is the color or the material important? Then better keep the handle as a separate object.

查看更多
太酷不给撩
7楼-- · 2019-03-08 11:35

I'd advise you to think about how you are going to use it. Think what operations you will have to do with your "thing" and then consider what would be the easiest way of doing it. Sometimes it will be easier to make it a property of another object, sometimes it will be easier to make it a new object of its own.

There is no universal recipe, there can be many factors that make one solution the better one. Just consider each case separately.

Added: To take your example about a door/doorknob/keyhole - what will you do with the keyhole? Here are some factors that would make it logical to make the keyhole as a separate object:

  • You want store many properties of the keyhole like size, shape, direction, count of pins, whether the key can be turned once or twice, etc;
  • There can be more than one keyhole on a doorknob;
  • You want to give the keyhole some read-only properties (like whether it's locked or not) and then only allow modifying them through specific methods (like an "unlock" method which takes a "key" object as a parameters);
  • Keyholes are stored in a separate DB table with one keyhole per DB row (then it might make sense to make the keyhole object mimic the DB structure);
  • There are methods in your system that would be implemented in an elegant way if they could take a keyhole as a parameter;

The scenarios for making it a property are the opposite:

  • Each doorknob can have only one keyhole and it has only one or very few properties;
  • Keyholes are stored together with the doorknobs in the DB;
  • You usually don't care about the keyhole alone, you just want it as a descriptive property of the doorknob (like whether or not there is one);
查看更多
登录 后发表回答