开发者

Replacement for C style struct in OOP

开发者 https://www.devze.com 2022-12-21 06:33 出处:网络
I am a student with a mainly electronics background getting into programing. The more I get into it, the more I realize how bad I am at it.

I am a student with a mainly electronics background getting into programing. The more I get into it, the more I realize how bad I am at it. I am trying to get better at OO design. One thing I have been reading about is the use of Getters and Setters.

http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?page=1 http://typicalprogrammer.com/?p=23

Now I can see the point they are making here but I am still unable to see away开发者_StackOverflow社区 around some simple problems. And this brings me to my question (finally). I am setting up a simple tower defense game in AS3 as a learning exercise. I want enemies to follow way points so I was going to make an array of way points, and make that a property of a map object. And a way point was to be an object with an x and a y property (more like a struct). Now I can see that this is exactly the sort of bad practice that the articles are discouraging but I can't seem to think of a better way to do this. Any help from some of you guys with a bit more experience would be much appreciated.


Firstly generalise; whilst you are currently wanting enemies to follow waypoints it seems to me that what you have is a specific instance of the map determining where something moves.

Let's call enemies an instance of "GameEntity" (possibly MoveableGameEntity).

What you should be doing is to tell the map to manage the relevant GameEntities, and then the Map can keep a list of these objects and move them as needed.

Code fragments.

interface  MoveableGameEntity
{
    void positionNotify(Position new_postition);
};

public class Barbarian implements MoveableGameEntity
{
    void positionNotify(Position new_postition)
    {
         // do something
    }
};

// during initialisation.
map.Add(new Enemy("Barbarian 1"));
map.Add(new Enemy("Barbarian 2"));

//during map processing
Position new_position = new Position();
for (MoveableGameEntityList moveable : moveable_game_entity_items)
{
   new_position = get_new_posistion(moveable);
   item.moveTo(new_position);
   moveable.positionNotify( new_position );
}

The map will need to have a method get_new_position(MoveableGameEntity ge) which will determine the new posisiton and the enemies will only be told their new posistion via the positionNotify method.

The MoveableGameEntityList is an object that will tie together a game entity and it's position. This way the game entity doesn't contain any position information and this is managed by another object.


Okay, heavy assumptions follow: I think you're thinking far too much about efficiency. OO coding isn't about efficiency. It's about elegant design. It's about minimizing side-effects from external factors and protecting internal state. This is why compilers "optimize." You should be thinking about maintainability and difficulty of coding primarily. The amount of lines you write might well be greater than non-OO code. That's not the point.

Try to think about your "objects" as tangible items that communicate with each-other. This communication is a protocol (includes method signatures). The language you "speak" to one another. Make it simple and unambiguous. Never assume that any object has the power to manipulate another beyond its ability to communicate a suggestion or request (encapsulation).

Don't just add getters and setters to everything without purpose. You'll miss the entire point and might as well be coding in another style. Protect internal state. Getters & setters on everything simply means, that you'll have a universally inefficient implementation. Setters & getters are gatekeepers. Nothing more. Eliminate them if they don't make sense. Use them where they do. Never allow something else to screw with your internal state. It'll create chaos.

When writing games, these practices fall down, but they're not to be abandoned. Optimize your critical loops & choke points. Keep your original code for reference & as a mirror-image model of your optimized code. Take the shortcuts you need and nothing more. Optimization must always come last... even in the face of an obviously inefficient, yet thoughtful, design.

Many ex-Java coders I've worked with put setters & getters on attributes unnecessarily (every attribute). This is simply what they're accustomed to. No benefit in 9 of 10 of cases, but they were insistent on this pattern. The impact was always negligible (50k users per minute... of course, not using Java... but still). The total impact of getters & setters is minimal in a high-level design. Lower level, as in video CODECs or OpenGL, it's huge.

You can choose to adopt them without thinking, or implement them with applicability in mind. You will find many professors telling you that you're "wrong" because you omitted them. Keep your coursework expectations in mind. :)


I prefer not to see this as bad habits vs good habits, but rather a shift in paradigm. Unfortunately, it's not as simple as just flipping a switch. It's something that happens gradually as you get more and more experienced with a different way of looking at things.

The best advice I can give you is to just start coding. A lot.


A bit unrelated, but if you want to get into OO design I have 2 v. good books for you, easy to understand & grasp.

Head First: OOAD

Head First: Design Patterns

0

精彩评论

暂无评论...
验证码 换一张
取 消