Object Oriented Programming

10 replies [Last post]
Posts: 465

Here is my Academic Journal which I wrote as part of my portfolio (other stuff was like reflection, game SDK, GUI system, design documents and diagrams).

As it is my first revision and some parts were rushed so I could get it in by the due date, until I get my marks please do not reference this in your work. Also until I make further revisions please do not distribute this to anyone, the only place this file should be is here. (Also I am wondering if anyone knows of a PDF protection utility so people can't just copy paste stuff off this).

I will also continue to make revisions to this whenever I can later on in life, also if you know a lot about OOP feel free to make any corrections because an Academic Journal is about peer reviewing. Hopefully I can eventually get it to a stage so that I can possibly publish this online to properly teach people about OOP, because at the moment its hard to get the right information both online and to a lesser extent in book format.

If you are a beginner or even intermediate at OOP (and is going to read this book), it is highly recommended to start from the top and work all the way down to the bottom, as it was designed to be read that way.

PreviewAttachmentSize
ObjectOrientedProgramming.pdf548.47 KB
Posts: 1691

I just browsed it quickly, but one thing that popped out was 3.2.11. I think you missed the biggest point on getters/setters for fields. Although they are often used to just get/set the private field, the point of them is to abstract from the underlying storage. For instance, a common optimization is to throw multiple booleans into a single integer value type. In many languages, if you change from a public field to a private field with a public getter/setter, you are changing the access signature, so other code using your code will have to be rebuilt. If you are already using getters/setters, you don't need to rebuild, just reference the new library, as all signatures are still the same.

In 3.2.10, you might want to add another sub-chunk of code showing that you can do the same in just one line with automatic properties, as this is the preferred way to much properties with a getter/setter with no additional get/set logic:

public int Speed { get; set; }

You might want to also add something about the singleton pattern. It is probably one of the most highly debated OOP concepts. Some people swear by them, others avoid them like the plague. I personally like them at times, and use them a few times in NetGore (just search for any class that contains the code " _instance;").

As for copy-safety, I highly doubt it. Even if you made it not natively copy-able, you could easily just copy by using OCR, which is quite common when it comes to PDFs.

In 4.5.7, I think you missed one of the key components of iterators - abstraction. They allow you to iterate through any collection in the same way, and usually in the most optimal way possible. By doing something like:

int sum = 0;
for (int i = 0; i < array.Length; i++) {
   sum += array[i];
}

you are stating that you do want to go one element at a time, from first to last. The compiler can't safely assume that any order can be used, that you can skip the accessor, or that it can be run in parallel. There are probably some important assumptions it can't make, either. But if you do this, it can:

int sum = 0;
foreach (var i in array) {
   sum += i;
}

Of course, a decent C# programmer would just write:

int sum = array.Sum();

Wink

Footer-note 6 on pg. 25 - I don't see how it would require more overhead in Java to have C#-like properties. Even C# just generates methods from it (ie: MyProp { get; set; } turns into get_MyProp() and set_MyProp() when compiled) since the CIL doesn't support "properties". It truly is just syntactical sugar.

Posts: 531

it looks tasty. don't have time to read it through yet, but from what i saw it is very well written, with some nice points. I'll link a pretty good site on Encapsulation i got shown, its eye opening. Like the home page says "Fight the complexity" Smile http://www.edmundkirwan.com/

There are 10 types of people in this world - Those who understand Binary and those who don't.

Posts: 465

Thanks Aphro

_____

Thanks Spodi I will get round to those changes asap.

Oh yeah bitflags for boolean getters and setters that's a good idea. Yeah the getter and setter point you mentioned was one of the really obvious things I completely forgot to put in haha.

The singleton pattern sounds like a great idea as I was pretty engaged into the debate at one point.

What do you mean by copy-safety?
EDIT: Never mind I worked it out now, completely forgot about the sentence i put in about the pdf. Tongue

I will hopefully have time to go way more in-depth with design patterns as I'm really interested in it. With the iterator pattern there were some good points I completely forgot to mention (like the ones you mentioned). However its probably not a good idea to get confused with the foreach loop and the iterator pattern. The iterator pattern does not allow access to elements in any order because the iterator is a linked list, it allows traversal in any order, going backwards and forwards one node at a time. So running all of the members in parallel is impossible, to do this some type of random access iterator is required. To access each member (in forward traversal) requires a hasNext() getNext() each node, then accessing the data from the node.

The foreach loop hides the fact that an iterator is created every loop and a number of getters are required before each member is accessed, which has some performance overhead (i created a collection class which got rid of all this and it ran 4 times faster). While it is syntactic sugar for the iterator pattern, it also provides extra functionality and some abstraction, this means that the foreach loop can have the capability for changes in the future without breaking anything (such as parallelism), however the iterator pattern on its own cannot.

For example

foreach (var i in array) {
   sum += i;
}

You could assume this would allow running in parallel, however with the iterator pattern this is not the case.

Iterator iterator = list.createIterator();
 
while( ! iterator.isDone())
{
      Integer i = (Integer) iterator.currentItem();
 
      sum += i;
 
      iterator.next();
}

or

Iterator iterator = list.createIterator();
 
for(iterator.first(); ! iterator.isDone(); iterator.next())
{
      Integer i = (Integer) iterator.currentItem();
 
      sum += i;
}

If you were to put some sort of logic in there such as creating a thread for each member each iteration, this would be exactly the same as implementing it in an array anyway. You can also use foreach loops for arrays, which you can't do with the iterator pattern.

However iterators do work better in multi-core environments, because each loop has its own instance of an iterator (usually).

As for overhead, what I meant was compiler overhead. I know it's stupid and I'm in complete disagreement with all the points that were mentioned, I put it in there so I wasn't biased and gave multiple points of view. Smile

Posts: 458

really looking forward to reading this!

I have a feeling that I dont know a BIT about OOP.

WHat I know as OOP is nothing xD

thank you a lot for upping this, I dled it and will definetely read into it next week

May I print this out?
In germany I doubt anyone of my friends (only 1 of em is into IT)
will be able or willing to read your english ^^

Posts: 465

Yeah sure that's fine haha.

Posts: 465

I got a High Distinction for my portfolio (90/100) and i chose the harder stream of programming for my course, so you'll be glad to know that the academic journal is up to standard. Ill hopefully have some changes done by next year, atm I'm still very busy with university (i have it over the summer holidays Sad), i also have some web dev work to do.

Posts: 44

School ftw

Posts: 465

Posted this up in the big programming thread on TL.

http://www.teamliquid.net/forum/viewmessage.php?topic_id=134491&currentp...

I cant be bothered finding and reuploading so I just plugged your site instead, thinking it probably wouldn't hurt anyway.

You may get an influx of visitors to your site, if you have any problem with this let me know, I have no problem removing the post. Smile

Posts: 1691

Great post, bake. I didn't read the whole thing, but I did have a few little notes. Sorry in advance if I misinterpreted anything, since I was speed-reading.

1.1.6: Your emphasis seems to be on performance, but something even more important in most scenarios is the amount of structure in OOP. A good OO design is both easier to maintain and consume, leading to improvements for maintainability and (given enough consumers of the object) productivity. This becomes increasing important as your framework grows and ages. But this comes with a cost - designing objects can be time-consuming because it requires you to put more thought into the design, and often leads to increase in consumption-oriented code (e.g. implementing the boiler-plate for various interfaces). For smaller, more simple, and especially "throw-away" code, it is often more time-productive to write code with very little structure.

3.2.11: "Therefore one should design a class that can collaborate effectively with other classes without the use of getters and setters". This makes it sound like optimal designs won't even need getters/setters, which is definitely not true. Thinking of getters/setters as "overly complicated ways to make a field public" isn't a good argument. If you have a getter/setter that just map to a private field, then it just so happens that, at the current time of the implementation of this object, the getter/setter does nothing more than expose a private member. The beauty of well-designed object is that, to the consumer, it doesn't matter at all. Sure, it may directly map to a private member now, but someone may change that in the future to map to, say, the 3 least significant bits of a byte used to store the compressed value of multiple properties.

While a C# property is just syntactical sugar (it provides nothing a get()/set() method wouldn't, and ultimately that is what the CIL generates if I remember correctly), it does allow the user to make certain, valuable assumptions as long as they are following the proper usage guidelines, such as:

  • It is cheap
  • Getters do not mutate state (though may throw when the state is invalid in the current context)

Compare that to something like strlen(), which has screwed with many people over many many years who falsely assume that it is a constant cost, not linear to the size of the string and is not cached.

Posts: 465

I completely agree with all of your statements.

This was written at a time when I was only doing Java, and unfortunately I, like many others, listened to these dijkstra try-hards who would write very sensational articles to get their name out, and we would treat it like gospel. Many of these design pattern propositions "why extends & getter/setters are evil", "writing everything in interfaces", etc, arose out of a more fundamental problem in Java's design. If anything these articles could all be grouped under "why Java is evil".

Dynamic OO languages like Ruby don't have these problems, not only is extends no where near as fragile, multiple substitution is A ok through the use of mixins. Also because assignment is really just a method with an '=' on the end of it and parenthesis are optional, we don't need to make a distinction between methods and variables. Therefore when we designate a property on a class, it can be a variable a getter/setter or whatever you want it to be, as it is a completely trivial process when interchanging between a variable and just creating a method with an '=' on the end. There is no use for interfaces when you have duck typing, obj-c still allows you to write interfaces called "protocols", but that's because that's really all that they are.

In terms of designing things before hand, again I believe this is only a problem in Java because of its inflexibility. In Ruby, I often just write things, and then fix them up later as I go a long, and I will end up with a better structure than if I spent too much time thinking before hand, its very difficult to judge how things will be in the future. I guess the main thing is just make sure its flexible and you follow certain principles that help you to avoid traps later on.

The problem of the getter/setter thing, probably is due to, if you've ever worked on an enterprise java project, and you have 100's of lines of just pure getters and setters in a class. I always wondered if we just removed these and just had public variables our project would probably be 1/4 the size.

As I learn more and more about OOP the less I feel that a lot of the features of OOP are really needed. I now think its really just about objects that collaborate to achieve a common goal, and if your program does that, its OO. When I've thought about it like that, that's when my code started becoming easily maintainable and small, instead of just nice to look at. Before I would specialise/generalise, write lots of interfaces, and then group like objects together in lists and etc. Then I was like fudge it, I'm just gonna create some classes that resemble real things that will work together to solve a problem, and when I see another problem, I create another bunch of classes for that, etc. When I see 2 classes that are doing similar things, I create a mixin. And if a problem can be solved stateless and functionally then I won't bother defining a method. Screw interfaces and polymorphism, screw patterns, screw types, screw encapsulation, screw nonsensical abstraction wrapper classes.

I could probably just write that first sentence and that would be my entire book on OOP. Tongue And really if we all wrote in smalltalk, OO would probably be a lot easier to understand and I would have less headaches trying to figure out these over-engineered designs and spending hours at meetings. Tongue