PDA

View Full Version : Where do YOU put your classes?


Groady
12-31-2008, 02:50 PM
I've been trying to tidy up some of my own custom classes lately and am trying to decide on the best way to structure my classes.

I'm wondering how YOU structure your packages when working on a project. I find there are certain classes I use regularly (like a custom Math class) and others which are created specifically for the current project (like custom DisplayObject's etc).

I'm trying to figure out if it's best to keep all classes within a master root package OR is it better to separate re-useable classes from project specific classes? I can see a benefit of manually copying classes to a local project structure for backup purposes. Having a global library could cause problems if a method gets renamed and a old project needs re-compiling.

What do you think?

yell0wdart
12-31-2008, 03:04 PM
I generally create packages for specific things. I've got a set of utility classes that I reuse across several projects that I keep in a separate package/assembly. With project specific stuff, it's important to create a folder structure that reflects the programmatic structure of your packages, rather than dumping everything into some nebulous "global" namespace.

kkbbcute
02-07-2009, 02:51 PM
Hows this, I don't even use classes. Never liked it. I'd rather have a 500 line long onEnterFrame function than a class as I like having all the code I'm supposed to be working with all in front of me at the same time so that I can debug more easily if the need arises, as all of my code are in one place. I just use 'for' loops to place any code I need on individual MCs which are named like mc1, mc2, mc3.

It's just me though, wonder if anyone else finds classes weird.
(Not saying that classes suck or anything, just saying that Ifind that I can do without them)

maskedMan
02-07-2009, 10:31 PM
I understand where you're coming from kkbbcute, as I once felt the same way. I think it depends really on how you structure your classes whether it's going to be easier to debug a 500 (or is it 5000) line onEnterFrame event than your class library.

For my money, it's much easier to debug classes than a giant procedural program. When objects are well-encapsulated and decoupled you remove needless dependencies, thus making a change in one place runs very little risk of causing unintended screwups elsewhere. Programming abstractly can allow you to swap class objects seamlessly either at compile time or at run time. While there was a time that I liked to be able to "see it all in one place", I've come to prefer only seeing what I need to see at any one time, and a good class structure lets you do just that.

Also, I suppose if you use the IDE exclusively to write your code and don't have a proper developer's tool like FlashDevelop (free) or FlexBuilder (not free) then managing a class library can be painful and require a lot of mental overhead that would be better spent on writing the code. The Flash IDE, since it doesn't recognize your custom classes in its auto complete and doesn't have a fully featured project panel, just makes writing a class-architecture harder than it needs to be.

senocular
02-07-2009, 11:07 PM
For general, everyday, reusable classes, I put them in the standard, reverse-domain package structure starting with com.senocular followed by, if possible, the directory name that mirrors what its location would be if it was a native class in the player in the flash.* package. For example, my VirtualMouse class is located in package com.senocular.ui since in flash, most mouse-releated classes are located in flash.ui.

When working with project-specific classes, the same convention is used if the project has its own domain. For example I have a little Flash app with its own domain and its classes are all stored in com.myavatareditor.* because that's where it lives.

If a project does not have its own domain, it usually just gets a single top-level package directory named after the project itself. An example would be something like (now looking at one of my smaller projects) creatures.*.

If any project is to use classes from another source, such as the creatures app needing to use something from com.senocular.*, I would physically copy those com.senocular.* classes over to my creatures project directory. This does a couple things. This gives me access to all required classes in one, easy to find location, makes it easier to package up all source code with its dependencies if needing to give it to someone else or post somewhere publically, and keeps changes from that original code affecting the project since it has a copy of that code in a state where it is known to work for that project.

So... all my general-purpose classes I have somewhere on a common place on my hard drive, but no project actually uses them from that location. Instead they have copies of those classes in their respective project directories with other com.* classes or their own projectname.* classes.

That actually reminds me. In cases where I have projects with classes I think would be reusable or useful in other places, I'll usually throw them into com.senocular.* which I've wanted to do with some of the creatures classes for a while but never have.

-Ev-
03-10-2009, 04:03 AM
I've got a very similar approach to senocular. All my personal reusable classes live in a Code folder on my hard drive that is simply a library of all classes I've written and felt were worthy of reuse. Root directory is com.evanwarner, and past that they are organized by category; data, layout, math, motion...whatever. Any time I want to use one of them, I copy it to my project's development folder.

My core belief is that any classes that collaboratively perform a job should be isolated in a package together. Methods and variables defined as internal should only be accessible to classes that will use them. Any standalone class that performs a job by itself can sit in the same package as other standalone classes, since all access is either public, protected or private.

A project's package organization is the same as my library...com.evanwarner followed by packages according to function of the classes.

dimpiax
03-10-2009, 08:32 AM
I have such structure of my projects:


Project:+ classes
+ ...
+ com.project.view
+ ...
+ deploy
+ data
+ assets
main.swf

It's very useful :)

Robbus
03-10-2009, 09:05 AM
Out of interest where/when/why did 'com' become the generally accepted default name for the top level classes directory, why not 'classes' for example, or even just 'c'?

Cheers,
Rob

-Ev-
03-10-2009, 01:39 PM
It was in effort to make package names unique and create a standard naming convention. Your website URL is unique, so it was a good candidate to use for package naming. It also sort of provides a way to find the author. It was reversed to com.* for two reasons:
1. To provide a more common root folder for packages instead of having all these unique names.
2. To prevent the possible confusion of seeing myurl.com. We automatically see that as a web address, but com.myurl is obviously not a web address.

I'm actually not sure if AS package naming was the first instance of this convention. I've seen it used other places. If you're on a Mac, go into your preferences folder, you'll see that a majority of the preference files are named com.apple.*.plist, com.adobe.*.plist, etc.

Robbus
03-10-2009, 02:04 PM
Thanks Ev, I should've said mine was a more generalised question. So what did developers use before the whole internet thing as obviously there wouldn't have been .coms for us all to get excited about?!

Cheers,
Rob

DougyTheFreshmaker
04-03-2009, 05:43 PM
Though I'm not certain, I believe the domain style naming convention for packages comes from Java and is used to avoid name collisions. The naming conventions and, to a lesser extent, the specific directory structure of packages are not be the driving force behind package organization.

Package level and class level dependencies drive package organization, and packages represent (non)reusable modules. Dependencies should flow in the direction of stability, be acyclic, and support reusability if desired.

Classes may conform to these ideas by depending only on interfaces, often through the use of dependency injection. Complete abstractions, in this case interfaces, are less likely to change than any concrete class. As long as a concrete class only depends on interfaces, its dependency graph will remain acyclic, and its dependencies will be stable. Reuse of these classes is simple as they may be moved to a new program without alteration, given that some implementation of the interfaces they depend on exists.

Packages are not managed with comparable ease. A package may consist of interfaces, concrete classes, or both. A package with only interfaces offers little benefit by itself, but a package with only concrete classes is too unstable for anything to depend upon it. All three types of packages are useful, but the direction of the dependencies is clear for two of them: nothing must depend on concrete-only packages (but these packages may use others), and anything may depend on abstract packages. The mixed case is more involved.

A rule of thumb is that packages which are subject to reuse should provide public interfaces for others to depend upon.

If a "Doors" package provides an "ILock" interface for locking mechanisms (ILock belongs to the Doors package), a "Locks" package might implement this interface. The consequence is that the Locks package now depends on the Doors package and cannot be reused without it. This may be acceptable depending on the developer's needs. The Locks package might, then, belong to the Doors package (Doors.Locks).

If reuse of the Locks package was desired, but reuse of the Doors package was not required, then the Locks package might provide a "IDoor" interface for the door to conform to (if necessary). Similarly, the Doors could no longer be reused without reusing the Locks package as well.

If independent reuse of both packages was required, then each package could provide the appropriate interfaces and a third, non-reusable package of adapters could be implemented to connect the two for a given program.

If both packages were to be reused, but never independently, then the two could safely exist within a single package.

A package's dependencies will determine its actual location.

Finally, packages need to be managed through a version control system. Copies of package code, if made, should not go out of phase with one another.

This is a well-studied topic. Robert Martain's article on Stability (http://www.objectmentor.com/resources/articles/stability.pdf) is a good start. An even better introduction, though less general, is this article on Dependency Inversion (http://ctrl-shift-b.com/2008/12/examining-dependency-inversion.html) (though, strictly speaking, the DIP is a class-level principle). Most of, if not all of, this post is a restatement of those resources.

yell0wdart
04-04-2009, 06:34 AM
This is a well-studied topic. Robert Martain's article on Stability (http://www.objectmentor.com/resources/articles/stability.pdf) is a good start. An even better introduction, though less general, is this article on Dependency Inversion (http://ctrl-shift-b.com/2008/12/examining-dependency-inversion.html) (though, strictly speaking, the DIP is a class-level principle). Most of, if not all of, this post is a restatement of those resources.

This.

Robert Martin is the man. Great author. He's got a great book on Agile Principles and Practices (one each for Java and C#). Very good read. Not AS specific, but the principles apply to any OO project, regardless of language.

/edit

I generally structure my classes and interfaces in much the same way that Sen mentioned.

@kkbb, not to put you on the spot, but you should really look into OO design principles and design patterns. A guy as smart as yourself shouldn't have too tough a time picking it up, and it'll give you a very powerful tool as you continue learning and growing as a developer. As others have said, it makes debugging and maintenance MUCH easier than working with a 500-line event made up of procedural (spaghetti) code. ;)

kkbbcute
04-04-2009, 07:35 AM
@kkbb, not to put you on the spot, but you should really look into OO design principles and design patterns. A guy as smart as yourself shouldn't have too tough a time picking it up, and it'll give you a very powerful tool as you continue learning and growing as a developer. As others have said, it makes debugging and maintenance MUCH easier than working with a 500-line event made up of procedural (spaghetti) code. ;)

Okay, I'll try, although my current situation doesn't really require such but I always try to learn (although my AS3 now still sucks, just don't get why we have to pile handlers and listeners just for simple functions to work) Anyway from the time I made the post here saying that I didn't use classes, till now, I've learnt to implement and extend classes already, so it's a good start! ;)

Right now though, I'm more limited by Flash's performance ratrher than code complexity, for example, many of my faux 3D lighting engines perform terribly (4fps what?!?!), so optimization is still a priority, does classes help in optimization in any way then? Just curious.

yell0wdart
04-04-2009, 08:33 AM
Anyway from the time I made the post here saying that I didn't use classes, till now, I've learnt to implement and extend classes already, so it's a good start! ;)

Definitely. Keep at it. ;)


Right now though, I'm more limited by Flash's performance ratrher than code complexity, for example, many of my faux 3D lighting engines perform terribly (4fps what?!?!), so optimization is still a priority, does classes help in optimization in any way then? Just curious.

It won't do anything really for your performance. What you will gain from it, though is modulatiry, ease of maintenance, extensiblity and reusability. :)

maskedMan
04-04-2009, 08:23 PM
Actually, using OOP can in fact make your performance worse if you take abstraction and delegation too far. A function call is always more expensive than a direct reference to a property, and a long inheritance chain is more cumbersome than a short one when performing operations. Instantiating an object too, is expensive in itself which is why there are such things as object pools to limit the amount of instantiation.

Having said all that, it's rare that your code will cause nearly a quarter of the lag that simply rendering graphics will. You'd have to recursively call functions a ridiculous number of times to match the sheer weight of graphics rendering. That is, unless your code is recursively rendering, processing, and modifying graphics like a madman. Then you're kind of down a creek either way you look at it.

fireant
04-04-2009, 11:35 PM
I'm where kkbb is... I am writing a few hundred lines of code in the actions panel just like I did for years in AS1 and AS2. I am comfortable with it, and dont see it as a problem that needs to be fixed.

Using the packages/classes/multiple files looks like it would just slow me down by adding another layer of complexity on top of learning all there is to learn in AS3. Its already a long walk for a short drink compared to AS2 (though it does play faster).

What I'd like to know is if there is really any advantage to package/classes or is this just a matter of developers who are previously experienced with this type of thing for other languages are used to doing it when the pick up AS?

BTW, I do keep a separate .as file with all my most-used scripts in it. For instance, if I want to make a custom cursor, I just find where "cursor" is in my well-commented master .as functions list and copy/paste it into my project.

maskedMan
04-05-2009, 12:28 AM
What I'd like to know is if there is really any advantage to package/classes or is this just a matter of developers who are previously experienced with this type of thing for other languages are used to doing it when the pick up AS?


I've already answered that for myself in my first post in the thread. A little background might be helpful in addition to that, though. I never considered myself a programmer when I was in school, and I certainly didn't focus my efforts in that direction beyond a few entry level classes involving Java, C, and Assembly for the purpose of fulfilling elective credits. I was a media arts major, and I coded to the extent that it would get Flash to do things that the authoring tool on its own was incapable of handling.

I've gone over time from where you stand to the standpoint of writing multiple class files and polymorphic objects and working almost entirely in as files.

I will say again, don't write your AS in the Flash IDE if you want to take a stab at structuring your code this way. Use a real developer's tool. The difference is night and day. I too would be slowed down if any time I wanted to open a file I had to do it through the flash 'open' command or click from a windows directory, and I would be massively slowed down if I were to use a tool that doesn't have an actual intelligent auto-complete feature. The flash authoring tool is just a flat-out poor coding environment.

The master .as file is reasonable (though not extensible which is a major consideration), and if you are the sole worker on the project it is easy enough to manage. What happens though, when someone else has to look at the code you wrote? Where do they look? Have you sprinkled code in many timelines? On many frames? Flash does have a way for you to 'jump to' code on timeline frames, but it doesn't give you any clue as to *where* a particular piece of code lives in the fla, and if you don't know where to look (a real possibility that grows exponentially the longer you go without opening the old .fla) then good luck finding it. :)

fireant
04-05-2009, 12:33 AM
Any recommended developer's tools for Mac? :)

My master .as function list is a bbedit text file.

maskedMan
04-05-2009, 12:49 AM
Since I don't code on a mac, I can't say as I do.

My IDE of choice is FlashDevelop and while there isn't a Mac port for it you can apparently run it on parallels http://www.flashdevelop.org/community/viewtopic.php?t=2463&highlight=mac

kkbbcute
04-05-2009, 04:01 AM
Hey maskedMan, you'll be suprised at the amount of lag that several hundred lines of math can do, especially when you want to calculate things like global illumination and faux per pixel lighting for objects and all that. It all basically comes down to loops and more loops. And I'm still learning AS3 after 2 years in AS2, so like fireant, that's a lot of work for me! (though I embrace challenges, which is why I'm coding all that weird lighting engines in the first place!)

P.S. Does anyone see any benefit in doing a per pixel lighting and global illumination system for Flash? If not then I'll cease production and look into classes like you guys recommended.

maskedMan
04-05-2009, 04:14 AM
Hey maskedMan, you'll be suprised at the amount of lag that several hundred lines of math can do, especially when you want to calculate things like global illumination and faux per pixel lighting for objects and all that.

It's not the slightest bit surprising, considering that I said that graphics manipulations and related math is the heaviest thing you can do in flash. :)

I'm sure you've read many articles about code optimization, and many of them focus heavily on picking nits (proper data typing, whether x++ is faster than x=x+1, and so on) but in the grand scheme of things the operation times for those individual functions are so small that you're certainly better off optimizing your algorithm than optimizing your data typing or your choice of operators.

As for working on graphics rendering algorithms vs teaching yourself OOP, there's no reason you can't do both at the same time.

kkbbcute
04-05-2009, 04:24 AM
As for working on graphics rendering algorithms vs teaching yourself OOP, there's no reason you can't do both at the same time.

Like fireant said, it's best to only do the most important one at a time, so you won't get too confused, and make that three (I still have AS3 to learn). Hmmm... Seeing that OOP does have its benefits, like the last 10 people or so have said, I think I'll go with it. But one thing, must the file be a .as file, can't it be a .txt or something (I just want an instantly recognizable suffix to seperate it from my other .as files)?

Side note: And maskedMan, seeing that you are familiar with loops and stuff, could you lend me a hand in my thread in the AS2 section? ;)

maskedMan
04-05-2009, 04:30 AM
All your classes have to be .as files. On the plus side, a good package structure totally removes any confusion as your generic non-classed .as files won't be living there.

kkbbcute
04-05-2009, 04:37 AM
Thanks for the clarification.:)

Darn, oh well, never mind then, I'll live with .as files for the time being...

maskedMan
04-05-2009, 04:39 AM
It's been a while since I have done anything in AS2, and about a year since I touched color gradation. I can tell you though, that you might want to try doing this in AS3 instead because of the quicker code execution. Just to give you some insight into the differences, in case you haven't seen it, check out this link:

http://blog.greensock.com/tweening-speed-test/

While this site is mostly a display by Mr. Greensock of how awesome his tween engine is, it also really drives home the orders of magnitude faster that AS3 executes.

kkbbcute
04-05-2009, 08:11 AM
Okay, thanks, will check it out!:)

Anyway, let's not go off topic.