Announcement

Collapse
No announcement yet.

Coding architecture

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Coding architecture

    I have been threatening to start this thread for some time.

    The matters I suggest have a number of purposes:

    1. Allow the development of D6 without prejudicing the functionality of D5.

    2. Provide a better source code structure than exists at present.

    3. Ensure that, as new features become available, there can be a release (D5.1, etc).

    Summary of current architecture: The architecture is based on a model-view-controller (MVC) paradigm, with the top level of the project split accordingly. Within each group there are sometimes sub-packages (model.military for example) and sometimes not (Civilization is just below model). Occasionally there are sub-sub-packages.

    In my view this is a misunderstanding of the MVC approach, which has as its aim the objective of separating out the actual functional calculations (model) from the merely display (view) elements, or input (controller) elements.

    The way coding is assigned in the Clash project, a coder is assigned a subject (Laurent has military, Mark has Economics, Sancio has Diplomacy, and I pretty much cop the rest, of which the most important is the GUI).

    This means that areas of interest tend to be spread around the top level packages.

    I would like to begin by arranging things differently. It is my belief that the MVC components of a single aspect should be in the same package, but performed by different classes. Accordingly, I would like the various models to have a top level class (game.military, game.economics, and so forth) with a libraries package as at present, and the present controller classes directly under "game".

    My suggestion is the the developing D6 code retain all the code for D5 (under the present MVC system), but make any changes in new packages under the system outlined here. Then provision can be made for switching between the old version and the new version. When the new version is seen to be working correctly, the old can be removed. This will require a certain amount of coordination between the coders, but it should be easier than the present system.

    The aim is that, at all times, the system compiles and runs, and is releasable.

    Cheers

  • #2
    Ok by me!
    Project Lead for The Clash of Civilizations
    A Unique civ-like game that will feature low micromanagement, great AI, and a Detailed Government model including internal power struggles. Demo 8 available Now! (go to D8 thread at top of forum).
    Check it out at the Clash Web Site and Forum right here at Apolyton!

    Comment


    • #3
      There is one general rule I would like to advocate. At present, aggregations are returned sometimes as Collections and sometimes as Iterators (and sometimes both). I feel we should use Iterators only, as being safer.

      Cheers

      Comment


      • #4
        I agree having a rule about Collection/Iterator returns is a good thing.
        I think we must provide copy services somewhere however, which use Collections.
        e.g. I have a Collection of Collections and want to retrieve leaf elements: I cannot use the Collection.addAll method which would be quite useful here. Do we have a utility class that would do the addAll stuff for an Iterator? If only I have the needs with the leaf elements, I can keep the code in the concerned class.
        Clash of Civilization team member
        (a civ-like game whose goal is low micromanagement and good AI)
        web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

        Comment


        • #5
          Laurent:
          You are right - where you want to build a collection from sub-collections, it is much more convenient to return the lower level collection, simply because of the existence of addAll.

          As far as I am aware, the only place this occurs is accumulating elements over Units, for combat purposes. Is this the case?

          If so, I would be inclined to provide a method in element like this:

          public addToList(Collection collection) {
          collection.addAll(elements);
          }

          and pass it the gradually increasing list, which dodges the problem.

          Cheers

          Comment


          • #6
            Hey guys,

            All of my methods return iterators (they actually return unmodifiable iterators).

            Gary are you going to code the GUI for the diplomacy model? Or you want me to do that? It doesn't matter to me either way. I just read that you are doing the GUI and don't know if you mean the general GUI or all GUI.

            Now let me see if I get your suggestions...

            You want me too include the modeling classes in game.model.diplomacy and the controller classes under game? What about the view classes?

            Later, I'll try to do some coding today
            Sancio

            PS Gary, I have some questions about compiling the code. I'll send you an e-mail.

            Comment


            • #7
              All of my methods return iterators (they actually return unmodifiable iterators).
              You have gone one step beyond me! How are the unmodifiable iterators implemented?
              Gary are you going to code the GUI for the diplomacy model? Or you want me to do that? It doesn't matter to me either way. I just read that you are doing the GUI and don't know if you mean the general GUI or all GUI.
              I don't have ownership of the GUI, it is just that I was experienced, and did what was necessary to get D5 out. So I am quite happy for you to code the diplomacy GUI provided it fits in with the general plan.
              You want me too include the modeling classes in game.model.diplomacy and the controller classes under game? What about the view classes?
              No, the game.model package is entirely D5. The diplomacy stuff will be in game.diplomacy, game.diplomacy.gui etc. I prefer gui to view because gui is specific and view is a bit vague. Also, it gives Mark a chance to go crook at me because I have been ranting on about not using abbreviations.
              PS Gary, I have some questions about compiling the code. I'll send you an e-mail.
              By all means. I won't get it for a while - I am at home now and don't get my email until I get to my office.

              Cheers

              Comment


              • #8
                It is my belief that the MVC components of a single aspect should be in the same package, but performed by different classes.


                Hi Gary:


                Whatever package organization you use is fine, altho I would like to politely disagree.


                For a 'system', the 'M-V-C' architecture seperates the code by function. All 'view' or 'graphical' classes go in one package -- java.awt or javax.swing, for example. All 'data model' code belongs in a seperate package -- i.e. java.util. And the 'controller' code has it's own package -- like javax.servlet, or java.io.


                With the 'Swing' components, they broke this convention somewhat. All the 'graphical' components like JTable, JList, JLabel, etc, *should* have been in java.awt. And the 'data model' classes like the TableModel and ListModel really belong in the java.util, I think.


                But they wanted all of the new stuff to all be in a single package, so they broke with convention and just put all the new stuff in the javax package.


                But this is not reccommended practice. Especially for a heterogenous system.


                Again, any package system you use is just fine, since it's largely a matter of personal organization. So please don't consider this a criticism.


                You're doing a tremendous job, and congratulations.

                Comment


                • #9
                  There are currently 30 packages in the Clash D6 system. Many of these have sub packages which are MVC subdivisions.

                  I have worked on projects with many thousands of classes in hundreds of packages.

                  The idea that they should be arranged, at the top level, into MVC super packages verges on the bizarre, as well as being enormously impractical. If done this way, and if all the game code is classified as "model" (which is incorrect), about 95% of the classes will be in the model package.

                  There is nothing at all in the original MVC specification which attempts to arrange packages - in fact packages hadn't been invented.

                  The real purpose of the distinction is to separate the IO model from the controller and view. This is done throughout the Java Swing system by having separate classes for the component (the view), the controller (the ActionListener) and the model (usually a model interface, such as ListModel). Which package these parts go into is irrelevant. In fact, for JList, the model and view are in the same package.

                  Cheers

                  Comment


                  • #10

                    • There is nothing at all in the original MVC specification which attempts to arrange packages - in fact packages hadn't been invented.


                      I agree completely -- this is all just personal preference. It isn't really even all that important, and the code will work exactly the same either way.


                    • The idea that they should be arranged, at the top level, into MVC super packages verges on the bizarre, as well as being enormously impractical.


                      The java classes are, in fact, arranged that way -- with the exception of the 'Swing' stuff. As you know, all that went into 'javax.swing', for their convenience in developing and introducing the components as an 'add on', or 'upgrade' to an existing codebase. As I certainly believe, this is all just personal preference. They preferred to put the entire release in one package.


                      I'm just sharing the approach we've used. If it suits you, cool. If not, I understand and respect your choice. I sincerely hope I'm not stepping on any toes with these comments.


                      The 'arrangement' of all the big systems I've worked on has been along the lines of --


                      • A 'projectname.data' package, analogous to the java.util package. This package holds all the 'data' code, and is typically the smallest of the packages, unless it's a *very* simple system.
                      • A 'projectname.view' package analogous to the 'java.awt' or 'javax.swing' packages. This package holds all 'gui' components.
                      • A 'projectname.controller' package analagous to either java.util or java.servlet. This is often the largest of the packages. All 'IO', 'business logic' and 'state management' code goes here.


                      Then these packages can have subdivisions based upon 'function'. Like 'game.controller.military', or 'game.data.resource', or 'game.data.technology'.


                      The main benefit to doing things this way, I've found, is that you can always find a class quickly. You always know where the 'Military Details View Panel' would be, for instance. The system isn't wierd, I promise! It works *very* well. It's very practical, especially with a large number of people working with a large number of classes.


                      I believe that's why they organized the 'java' base code that way, in fact (awt/io/util) . . . and I assume you don't consider that bizarre. It makes it *very* easy to find what you're looking for.


                      But as I said, if it doesn't suit you, I understand. I've seen literally dozens of code organization approaches, as I'm sure you have too.



                    This class has

                    Comment


                    • #11
                      It isn't so much whether it suits me, as whether it suits a system in which a number of coders are working on different "subjects" (they are called models, but I didn't want to use another meaning for an already overworked word).

                      It is certainly convenient to have all the military stuff together, gui and all, and a similar remark applies to economics.

                      The overall gui (the frames and panels) are in a package of their own at the top level, but go somewhat beyond a mere "view". They are at the top level because they are not part of any Clash model.

                      Other packages cover related topics - geography and government are two.

                      Oddly enough one of the reason behind this is it makes it easier to find things, though I must admit losing Selection.java which covers the army selected on the screen, which turned up in game.military.gui.

                      I don't take offense. As you say, there are many ways of achieving the same result.

                      I thought it better to arrange things by coders, at least in part because this is being done remotely with much less interaction between coders than you get when a project is in a single office.

                      Another point is that the code follows, fairly closely, the Clash model speciifcation, and I have tried to arrange the code so it can be more easily matched to the web site headings.

                      Cheers

                      Comment


                      • #12
                        I thought it better to arrange things by coders, at least in part because this is being done remotely with much less interaction between coders than you get when a project is in a single office.


                        This is a very good point I hadn't really considered.


                        Sorry for bugging you on something so insignificant. I'm just a completely hopeless computer geek, and that is just the kind of stuff that most interests me. So thanks for putting up with me.


                        Cheers!

                        Comment


                        • #13
                          Well, I have organized quite a few projects in my career, and I doubt whether any two of them had the same structure.

                          At least Clash isn't spread over a number of processors, with different operating systems.

                          Yet...

                          Cheers

                          Comment


                          • #14
                            I thought I had better put on record some things relating to coding practices. There are a number of books with good advice in this area. In particular Jacob Bloch's book "Essential Java" is very good. I will refer to this as [EJ]. Also "Java Design" by Peter Coad and others had some good stuff, though plowing through the junior stuff and the UML is tedious. I will refere to this as [JD]

                            There are, that I can recall offhand, four evils in Java. I do not propose to repeat the reasons why they are considered evil, but will just call them to your attention.

                            1. finalize
                            [EJ}, item 6 explains why you should not use finalize. Essentially it is because it is not guaranteed to work. If what you want to do is mission critical, don't use it. If what you want to do isn't mission critical, don't bother to do it.

                            2. Observer/Observable.
                            As included in the early versions of Java this system is flawed. It can only be implemented by extending Observable, and this breaks the "is a" rule for extension. Also the Observer interface is flawed because it requires the object passed in notify to be Obserable rather than Object. The consequences of these flaws (and the way of fixing them) is given in [JD] in the section on notification. Notwithstanding that, I do not like the publish/subscribe paradigm, because the messages sent by an observable object may be quite varied, but intended for a limited subset of subscribers (perhaps only one of them). In effect, to send a letter to a club memeber, you send a copy to all the club members and expect the intended recipent to read the letter, and all the others to throw their copies away. There really are better ways.

                            3. Serializable.
                            This is discussed at length in [EJ] Chapter 10. The comment there is "a major cost of implementing Serializable is that it decreases the flexibility to change a class's implementation once it has been released". In effect, the byte stream coding becomes part of the class's API, so, unless you customize the exported form, the system is forever tied to the original internal representation of the class. Quoting further "a secpnd cost ... is that it incrases the likelihood of bugs and security holes". And finally "a third cost ... is that it increases the testing burden associated with releasing a new version of the class".

                            4. clone
                            This is discussed in [EJ] item 10 (as opposed to Chapter 10). The problems are quite subtle, but ultimately arise from the fact that the interface does not define the clone method, and the clone method of Object is declared as protected. Essentially these flaw are fatal to reasonable use of clone. In addition, clone is an extralinguistic way of creating objects without a constructor. This is not good.

                            Cheers

                            Comment

                            Working...
                            X