Jump to content

Anders Melander

Members
  • Content Count

    2510
  • Joined

  • Last visited

  • Days Won

    127

Everything posted by Anders Melander

  1. I don't like this part; It sounds like you're polluting your business logic tier with presentation stuff. Even if you're just using the database and BO tiers for storage of the UI definitions, my guess is that you have created a strong binding between the UI definitions and the presentation tier, so the definitions can only be used by the one presentation tier(s). I've seen this done several times and it always ends up with half the UI being created the way you describe and the other done the traditional way because of special UI needs that the generic framework can't handle. And then eventually the need arises for a new type of client (e.g. web or mobile) that cannot use the existing UI definitions and slowly the definition framework decays because it turns out that it's faster to just create the whole UI on the client than trying to make the definition framework handle everything for everybody. It's a bit like the write once, run everywhere promise. Sometimes it just faster to write three separate applications than to have one application support three separate platforms.
  2. Sure. Professional relationships, personal preferences and even mood, are just some of the many factors that affect priority. We're humans. As long as you know why you are making a choice I don't see anything wrong with making it based on "feelings" or intuition. Just don't make all your choices that way 🙂 I regularly make technical decisions based on intuition. I may not be able to rationally explain why I choose one solution over another, except that one "feels" right or the other doesn't "feel" right.
  3. Even trivial changes consume project resources and resources are finite. Implementing a low priority change takes resources away from higher priority changes and unless there's something wrong with way changes are prioritized I can't really see how one can justify that. The really hard part is weighing all the different factors when calculating the priority. Giving a ticket priority just because it's old doesn't make much sense. But if the age will cause enough customer dissatisfaction that it ends up having economical consequences then it might make sense. Apart from that I don't think age should be a factor. Each time we go through our ticket list we look at it fresh: At this point in time, what is the most important change for us to focus on. In my projects it's common for trivial but very low priority changes to be rejected. I think it's better to let the requester know that there's minimal chance their request will ever be granted, given that there will always be more important changes to work on, than to give them false hope.
  4. I can't really tell from your statement if you're saying that he doesn't do that but should or if you're just stating a general principle. From the code posted it's not possible to see if the implementation uses aggregation and/or delegation. No. It's another way. Which is better depends on many factors and we can only guess since we don't know anything about the architecture or size of Clément's application, and it's not really relevant to the question asked. In my experience an application has to reach a certain size and complexity before it's worth even considering the overhead and added complexity of SRP. And even then I would only apply it if it solved an actual (present or near future) problem.
  5. I don't see any problems with it; It's a very common (and very sensible) pattern. Just make sure, if your base class is reference counted, that all references to the object is through interfaces. If it's not reference counted then that doesn't matter.
  6. Anders Melander

    Open Url From Current Line

    Code style to tentacles in three posts. I didn't see that coming.
  7. Very interesting. Thanks for the pointer. One of the other answers explains it even better IMO and points to this gem: https://kjellkod.wordpress.com/2012/08/08/java-galore-linkedlist-vs-arraylist-vs-dynamicintarray/ I guess I'll have to revisit some of my old code and redo the benchmarks.
  8. That's quite a unnuanced (is that a word?) statement. Wouldn't you say it depends on the access and allocation pattern?
  9. Anders Melander

    Open Url From Current Line

    That's a strange question. It's based on the experience that unnecessary nesting makes the code harder to read. Sure it's a personal preference, some like it, some don't (just google Early Return - I'm sure you will find one or two that doesn't advocate it), but at least one of your "if" blocks are complete superfluous and would be removed by the optimizer if it was worth anything. What's the relevance? Are you saying that because some simple rule based validator doesn't flag your code then it can't be improved? - Because I can spot several goofs in it.
  10. Huh? You have heard of premature optimization haven't you?
  11. Anders Melander

    Open Url From Current Line

    It's a refactoring; It improves the readability of the code without changing the functionality.
  12. Anders Melander

    Open Url From Current Line

    Nice. But: Early Return ... if ParamCount < 2 then Exit; if not FileExists(ParamStr(1)) then Exit; if not System.SysUtils.TryStrToInt(ParamStr(2), ThisLine) then Exit; ...
  13. Anders Melander

    Blogged : Introducing DPM - a Package Manager for Delphi

    Congratulations! I love it when that happens. I do think the phrase "Attempting restore on [...]" sounds a bit pessimistic though. Why not just "Restoring [...]"
  14. Anders Melander

    IDE title bar anomaly?

  15. Anders Melander

    System.Actions.TContainedAction.DisableIfNoHandler

    Yes, but you can't. I don't know the history behind it but I can see arguments both for and against having actions disabled if there's no handler and maybe that's why they decided to make it optional. Maybe not making it published was to avoid having the noobs shoot themselves in the foot with it. I don't know (and I don't care which is why I tried to delete my question after I asked it 🙂). It's a very minor annoyance that can easily be worked around with an empty OnExecute handler so I don't really care about it anymore. Submit a change request if it's important to you.
  16. Anders Melander

    Blogged : Introducing DPM - a Package Manager for Delphi

    I'm way past caring about disk space. For example we use DevExpress in almost all desktop projects and in addition to the regular install, which we need for design time support, help, examples, etc., each project has a complete copy of the DevExpress source files to make sure the projects are autonomous, under full revision control and are always built with the correct version. That's 120 Mb in 3000 files - per project, per branch, etc. Yes, a global package cache could reduce that to a single copy, but it would be pointless. The problem we have isn't disk space. It's creating a reliable, robust and foolproof development environment. Yes, but I would prefer to have complete control over where that exact location is. I'm not saying that it's unreasonable to require at least some adaptation of a project for use with DPM but for me at least it will be a showstopper if use of DPM becomes a requirement once the project has been adapted and having the package cache in the project search path, and the search path controlled by DPM, is such a requirement as far as I can tell. I guess right now I'm focusing on how DPM could fit in with my existing projects where I already have all dependencies sorted out and folders and search paths assigned. I understand the use cases of dependency resolution, the package cache and updating the search path, but I'm not sure the convenience they offer is worth sacrificing the autonomy I already have in place for the projects I manage. Now if only DPM had been a standard part of Delphi then it would have been an entirely different matter.
  17. Anders Melander

    IDE title bar anomaly?

    My guess is that you have two monitors; Primary with 125% zoom and secondary with 100% zoom. This setup appears to freak the IDE out.
  18. Anders Melander

    Blogged : Introducing DPM - a Package Manager for Delphi

    I would have preferred it to be zero or one copies: The package cache would just contain the meta data and optionally a single copy (per version) of the source files. On update the package manager would copy the specified source files to a local folder specified in the project options. This way there would be no dependency between the project and DPM and the the project would be completely autonomous. As far as I can tell, the system you have now creates a dependency between the project and DPM because the project search path has to include DPM specific folders - local or not. There's also a duplicate binding between the project and the package version because the version is specified in both the dpm.config file and in the project search path. It should be sufficient to specify the version in the config file.
  19. Anders Melander

    Blogged : Introducing DPM - a Package Manager for Delphi

    That's not my understanding. As I read it the package cache can be either global or per project. Regardless I can't see the problem of each project having their own copy of dependent libraries - unless it's the JCL in which case even a single copy is a problem 🙂 Disk space is cheap. Time is not.
  20. No. But while you're peeking at the message queue you might as well do something useful with it: procedure BusyBusyBusy; begin // Allow threads to synchronize CheckSynchronize; Msg.message := 0; try // Process cursor update messages for this window so cursor stays responsive while (PeekMessage(Msg, Handle, WM_SETCURSOR, WM_SETCURSOR, PM_REMOVE)) do begin if (Msg.message = WM_QUIT) then exit; DispatchMessage(Msg); end; // Process paint messages for all windows so UI can repaint itself while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) or PeekMessage(Msg, 0, WM_ERASEBKGND, WM_ERASEBKGND, PM_REMOVE) or PeekMessage(Msg, 0, DXM_SKINS_POSTREDRAW, DXM_SKINS_POSTREDRAW, PM_REMOVE) or PeekMessage(Msg, 0, WM_PRINT, WM_PRINT, PM_REMOVE) or PeekMessage(Msg, 0, WM_PRINTCLIENT, WM_PRINTCLIENT, PM_REMOVE) do begin if (Msg.message = WM_QUIT) then exit; DispatchMessage(Msg); end; PeekMessage(Msg, 0, WM_NULL, WM_NULL, PM_NOREMOVE); // Avoid window ghosting due to unresponsiveness on Vista+ finally if (Msg.message = WM_QUIT) then begin PostQuitMessage(Msg.wParam); Application.Terminate; end; end; end; The above was snipped from existing code so might need to be tweaked slightly.
  21. Anders Melander

    need help with graphics32 library

    OK. Good luck then.
  22. Anders Melander

    need help with graphics32 library

    You don't need to open the form to compile the project. But if you need to see what the example source looks like, open the unit, ignore the error messages about unknown components, look through the source, close the unit without saving the changes.
  23. Anders Melander

    need help with graphics32 library

    No it doesn't. Looking at the source also doesn't require installing them I'm a contributor to Graphics32 and I don't have the component installed.
×