Results 1 to 10 of 12

Thread: [opinion][Research] API design

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    After thinking some more on this topic I must admit that I'm becoming less and less inclined to your second approach of using using unit names instead of prefixes. Why?
    As you pointed out yourself calling certain method that is implemented in multiple units with same name without providing unit name will lead to unexpected behavior. I'm not sure about FPC but in case of Delphi I believe the method from the unit that was last loaded would be called in such scenario.
    Another disadvantage of such approach is that you are basically forcing yourself to have each system in its own unit. While often this is perfectly fine there are times were you might want to have several connected systems in a single unit in order to improve code readability.
    Wouldn't this also mean that you will have to ad every unit into uses section of your main application unit?
    Also having bunch of small units could have significant affect to build time. Now wile Object Pascal compilers are know to have very fast compile times due the fact that only modified code is recompiled having bunch of small units could still lead to long build times. This mostly due the fact that linker still needs to link a bunch of small compiled code pieces together in order to build final application.

  2. #2
    You have some points here.

    I was coding some time now and besides the build time it seems nice to me. Thankfully Lazarus is able to rename all references by itself, or I can use a tool I wrote some time ago to help with Allegro.pas development, so if I change my mind I can change all identifiers. It isn't TRUNK yet.
    No signature provided yet.

  3. #3
    Real life strikes back.

    I was working on the disk access API, and I've found some of the issues you, SilverWarrior, were talking about. Of course, using the unit name fixes all problems, but I spend some valuable time wondering if TStream should be the original Classes.TStream or the one I extended...

    So I've decided to back to the prefix. It was a nice experiment though.
    No signature provided yet.

  4. #4
    Quote Originally Posted by Ñuño Martínez View Post
    but I spend some valuable time wondering if TStream should be the original Classes.TStream or the one I extended...
    One piece of advice. If you are extending some class with new functionality it is recommended to change the name of the extended class in order to avoid confusing it with the original class that it was extended from.
    That is unless you want your extended class to be used as a base class for other classes that have been extended from the original class and thus in a way inject additional functionality to all of them.

  5. #5
    Maybe this:
    <Action><Object><Attribute/State>();// Do an Action over some Object Attribute/State
    This is how I tend to make my APIs, more info about this here:
    raylib syntax analysis · raysan5/raylib Wiki (github.com)

  6. #6
    The second one BUT use classes with class (static) methods instead of unit names.
    This way you *cannot* call method without specifying which.
    And can pack several ones in the same unit
    And move them between units if you need to change architecture -- without touching the calling code

    in my engine:
    GAPI.TexImage2d(p, format)

    where
    class function GAPI.TexImage2d(
    image: pointer;
    format: TGAPITextureFormat;
    level: GLuint = 0;
    width: GLuint = 0; // 0 = get from image
    height: GLuint = 0; // 0 = get from image
    CreateTextureObject: boolean = false
    ): GLuint; //no return value unless CreateTextureObject is true

  7. #7
    There are a lot of nice advices here. Thanks to all.

    Quote Originally Posted by SilverWarior View Post
    One piece of advice. If you are extending some class with new functionality it is recommended to change the name of the extended class in order to avoid confusing it with the original class that it was extended from.
    Yes, I've learned that the hard way.

    The injection thing is interesting but I think I'll not do that way.

    Quote Originally Posted by drezgames View Post
    Maybe this:
    <Action><Object><Attribute/State>();// Do an Action over some Object Attribute/State
    This is how I tend to make my APIs, more info about this here:
    raylib syntax analysis · raysan5/raylib Wiki (github.com)
    That's a nice way. Maybe I should review my API now I'm (re)starting it.

    Quote Originally Posted by Chebmaster View Post
    The second one BUT use classes with class (static) methods instead of unit names.
    This way you *cannot* call method without specifying which.
    And can pack several ones in the same unit
    And move them between units if you need to change architecture -- without touching the calling code
    I didn't realize I can do that. I did in some PHP projects but forgot completely there are also static class methods and properties in Pascal. Since I'll revisit my API I'll see how this may fit with the old-school I want to archieve.
    No signature provided yet.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •