Whilst moving some applications from Delphi XE2 to XE5 I've noticed that there are a number of units listed which are no longer needed.
This is turn lead me to tidying up the uses section of the interface which leads to my question.
Is there a recommended order for units in the interface? I know they are loaded in reverse order, but should I be organising them by Usnit Scope.
For example should MyCompany.* be listed at the start or the end? Should I place the Vcl.* before the System.*
update
In general I will include my Units in the implementation rather than interface. I'm grasping more about whether there is a hierarchy to Delphi's own units...
For example I have encountered one issue where listing the Windows unit before System.SysUtils changes the version of DeleteFile that is used...
Explicit Question
Should the order of uses be
Winapi*, System.*, Vcl.*, or the reverse?
There are some risks associated with uses list refactoring:
Later used units will override symbols (methods, classes, vars, consts, ...) of units used earlier (scoping).
This can introduce (more or less) sublte bugs into your program.
Reordering units can change the order in which intialization and finalization sections are run.
There are also some advantages:
Faster compiling speed
Smaller executables (Only if any removed units had initialization or finalization)
Avoiding / Preventing uses circles (although uses circles are often a sign of a sub optimal OOP design)
Having said that and after your question update:
I tend to do the same thing that David already wrote: Order the units from low level to high level.
There are tools that can help you with finding unused units and also arranging the used ones in the best order. (Peganza Icarus / PascalAnalyzer and ModelMaker)
It's hard to say what the compiler really does (especially since there are now multiple compilers), but putting units with the least dependencies first should make it easier for the compiler to build the dependency tree.
Read http://docwiki.embarcadero.com/RADStudio/XE3/en/Programs_and_Units and http://docwiki.embarcadero.com/RADStudio/XE5/en/Using_Namespaces_with_Delphi articles.These 2 articles are explaining exactly what you've asked.
The TMS Software, author of many components for Delphi - recommend on their blogpost the following order:
uses
// 1. fpc/lazarus/delphi units,
// 2. 3rd units,
// 3. my open source units,
// 4. project units
It is actually the best option in my opinion. You can change the order. Important is only to remember that when the function/class name will be used in more than unit, the last one unit will be used.
Related
I am wondering if the following using unit order is correct.
uses
FastMM4 in 'Fast\FastMM4\FastMM4.pas',
VCLFixPack in 'VCLFixPack.pas',
FastMove in 'Fast\FastMove\FastMove.pas',
FastCode in 'Fast\FastCode\FastCode.pas',
FastMM4Messages in 'Fast\FastMM4\FastMM4Messages.pas',
Why should I bother with the order?
There may be a few reasons:
Some units perform actions at startup. The order of such actions may be important, like FastMM4, which replaces the default memory manager with its own. This should be done before any memory is allocated.
If several units contain duplicate identifiers, the "last" one overrides the previous one. This may be on purpose, or it may be by accident. The other identifiers are still accessible, but not without qualification with the unit name.
The same as for actions at startup, actions at the end of life my be important too, and their order.
Note that it is not guaranteed that the order is preserved. If one of the units uses another, that one must be loaded first. To make a unit really the very first, make it the first in the .dpr or .dpk file.
You have three separate pieces of code here:
FastMM
VCLFixPack
FastCode
It is important to install the replacement memory manager, FastMM, before any heap allocations are performed. So I think it is clear that must be the first unit to include. And you may as well keep the two FastMM units together.
The other units make changes to the code in memory, to fix bugs (VCLFixPack) or to improve performance (FastCode). Although you have separately identified FastMove and FastCode, in reality, the FastCode unit actually installs a suite of improved functions, defined over a dozen separate separate units.
It seems quite likely that it would be important to install the VCL fixes before the VCL units are included. So VCLFixPack should appear before any VCL units.
As for FastCode, since it only influences performance, you could perfectly well use it at any point in the .dpr file. It probably does not matter if the initialization code runs with the vanilla RTL code. That said, for sake of consistency it makes sense to keep together all these units which change the behaviour of the runtime. So I would write your .dpr uses clause like this:
uses
FastMM4 in 'Fast\FastMM4\FastMM4.pas',
FastMM4Messages in 'Fast\FastMM4\FastMM4Messages.pas',
FastCode in 'Fast\FastCode\FastCode.pas',
VCLFixPack in 'VCLFixPack.pas',
....
I put FastCode before VCLFixPack because logically the RTL is at a lower level than the VCL. However, it does not matter either way around. But you've got to pick one, and that was my reasoning.
I also omitted an explicit reference to the FastMove unit. That is used by FastCode, along with a host of other units, and if you are going to omit the others, you may as well omit FastMove.
I have a large codebase which I am working with which has units like this:
unit myformunit;
interface
type
TMyForm = class(Form)
end;
procedure not_a_method1;
procedure not_a_method2;
var
global1,global2,global3:Integer;
...
In short, the authors of the code did not write methods, they wrote global procedures. There are tens of thousands of them. Inside these procedures, they reference a single instance of MyForm:TMyForm.
I am considering writing a parser/rewriter utility that will turn this code into "at least minimally object oriented code". The strategy is to move the interface and implementation section globals into the form, as a start. I realize that's hardly elegant OOP. But it's a step forward from globals.
If I could do this on one unit at a time, I might be able to repair the breakage in the rest of the project, if I only did it on one form at a time. But I'd like to reduce the amount of time it takes to rewrite the units, instead of doing it by hand. Some forms have 500+ procedures and 500+ interface and implementation global variables which are in fact, specific to the state of a single instance of the form that they are in the same unit with.
Basically, what I will do if nothing like this exists is write a parser based on the Castalia Delphi parser. I'm hoping that perhaps ModelMakerCodeExplorer, or castalia, or some other similar tool has something that would at least do part of what I need for me, so I don't have to build this utility myself. Even if I do have to build it myself, I estimate it might automate about a thousand to two thousand hours of grunt-work for me. I can at least run it, and then see how much breaks, and then revert or commit after I've decided on a level of effort to refactor this code.
Alternative strategies that accomplish the same goal (go from zero encapsulation and zero OOP, to more encapsulation, and slightly more than zero OOP, in an incremental way, on a large, unstructured delphi codebase that only used objects when it was unavoidable, and never had any idea about real OOP) are welcomed.
Changing the globals to form fields seems like just cut and paste them. You might consider moving them in a dummy procedure and use MMX to normalize the declarations first.
Then use ModelMaker Code Explorer to move the procedures and functions into the form, which is only just cut and paste in the Member View.
Not necessary, but as a next step remove the references to the form instance from the method bodies. This can be achieved by find and replace.
Or did I miss something?
The Delphi Sonar plugin (open source) does not fix the code but can be used and configured to search for 'bad code':
The Delphi Sonar plugin enables analysis of projects written using
Delphi or Pascal. It was tested with projects written in Delphi 6, 7,
2006 and XE. This plugin is a donation of Sabre Airline Solutions. Its
tests include: Counting of lines of code, statements, number of files,
classes, packages, methods, accessors, public API (methods, classes
and fields), comments ratio, CPD (code duplication, how many lines,
block and in how many files), Code Complexity (per method, class,
file; complexity distribution over methods, classes and files), LCOM4
and RFC, Unit tests reports, Rules, Code coverage reports, Source code
highlight for unit tests, “Dead” code recognition, Unused files
recognition.
We have a project full of custom components that today is working in Lazarus and Delphi.
I'm thinking in code interfaces on it, but I am not much familiar with them. What I would like to know is: What are the implementation nuances from Delphi and Lazarus interfaces? There is something that I should be specially aware? Will I have to code really different things?
Background explanation:
I think the components could benefit from interfaces, or at least, I will learn more from them. For example, one of the components make communication to many different hardwares using serial port. But user should use only our component to create the application. So we have the component and one class to each of this hardware that descendant from a base class. At run-time we create the specific class inside the component.
Not sure this last explanation was needed, but I can write more if any of you need it.
In Free Pascal, the interface type depends on mode. Basically there is mode COM or CORBA . COM is default and roughly compatible with Delphi. CORBA is a more simpler case without the reference counting. (and thus also not generating calls to refcounting functions). So basically a FPC Corba interface is like the hypothetical ancestor of the IUnknown interface.
Besides this, there are sometimes some differences wrt when interfaces are released. Delphi tends to save decreasing the refcount at for the end of the procedure or block (in larger procedures), while FPC sometimes is known to release them sooner, typically immediately after the statement of last use. Both are legal implementation choices btw, base on which scope is used for temporary variables. (only on the function level, or also in deeper nested blocks)
However this sometimes reveals hidden (bad) assumptions in code, specially when using interface references and object references within one procedure that might "survive" in Delphi, but not in FPC. It is a typical case that shows that long-time working code is not necessarily correct. One might only notice hidden assumptions when changing implementation
(added later:) note that you can use COM style on *nix. It mainly is the insertion of calls to reference counting routines that set the two interface types apart. Not what system (COM, Corba or simply in RTL reference counting) those calls are routed to.
Note that I think the COM vs Corba names for both interface types were badly chosen. Corba interfaces are refcounted actually, but traditionally this refcount is manually handled, because Java does not support externally handled interfaces in an automated manner.
Added 2021-11-06: It seems that Delphi Alexandria now follows suit
I'm evaluating the many possibilities for a trial protection system and came up with the following question:
If I use my "trial check" class more than once (scattered several times over the application), will it be compiled just once into the exe?
The reason why I'm asking is that if it's only compiled once into the exe, then patching this single class will invalidate all places where it is used.
If it's compiled just once, are there any viable alternatives to prevent this?
Thanks!
EDIT: I'm actually not trying to roll my own protection system, I'm looking at several existing solutions like OnGuard, mxProtector and TRegWare. It was while looking at the various solutions source-code, that I came up with this question.
Yes, even if you create several instances of the class in different places there is only one copy of the methods (implementation), so if hacker patches the class all instances will be patched.
Do you really want to roll your own protection system? It ain't easy to come up with good system and there are several ready to use solutions around, if youre on budget then perhaps TurboPower OnGuard (which is open source now) will do.
BTW the general wisdom is that if they want to crack your app they will do it, no matter what, so one shouldn't waste too much resources on protection schemes. The only foolproof way is to exclude some of the (key) functionality from trial version, ie
{$IFDEF trial_version}
ShowMessage('Sorry, this function is not available in trial version');
{$ELSE}
// do the thing
{$END}
but of course, if full version gets into wild then it will be cracked...
If you use the inline keyword for functions and methods where possible, the executable code will be "multi-plicated". There are some limitations to the use of inlining, though (see the linked doc).
I agree with Ain and Marco that spending effort on protection schemes may be more bother than benefit, and that it makes more sense to use existing solutions than to roll your own.
Yes. The standard workaround is to put the code in an .inc and include that in multiple units.
But that makes less sense in a security setting. Since if sb has learned to search for a pattern, he can simply repeat the search to find the other occurrences, making it a minor nuisance at best.
This is one of the reasons why DIY protection is often a waste of time, and I agree fully with Ain. (both the onguard thing, and the fact that if functionality IS in the exe, it will be unlocked sooner or later, giving sufficient motivation)
Just for the principle: There is actually a possibility to have the "same" class compiled multiple times. If you declare the class with a generic type and later have several instances with different instance types, the class code is compiled for each type. The generic class don't even have to make use of the generic type. If you spread the generic instances over different units, the code will be separated, too.
type
TDummy<T> = class
public
procedure Dummy1;
end;
procedure TDummy<T>.Dummy1;
begin
...
end;
var
FDummy1: TDummy<Integer>;
FDummy2: TDummy<Byte>;
FDummy3: TDummy<TButton>;
FDummy4: TDummy<TLabel>;
I've been using Delphi for a little over a month, but I still do not know the proper way of doing things.
If I have methods which I can use on a lot of projects should I put them on a Unit, Form or DataModule?
I have not used a unit (in itself), New-> Unit. Should I put my utility methods there? If so, is there an example I can look at, a tutorial or whatever.
I've used DataModules in the past, though it gives me the impression that it should only be used when I'm dealing with databases and such.
Another thing, I'm customizing some forms (for instance a form with some TEdits that do specific things).
To use this, first I add this to the uses in the .dpr
CustomizedForm in '\CForm\CustomizedForm.pas' ;
then I add CustomizedForm to the uses in my mainform (where I'll be using it).
Is this the correct way to do it? I'm was just guessing, it seems to work though I'm not particularly confident that it's the proper way.
I put all mine in a unit called utils.pas. It works for me.
If you have different segmentations of utilities that some programs use but not others, you may want to create separate units for them.
Look at: Anatomy of a Delphi Unit
It is part of the excellent Beginner's Guide to Delphi Programming by Zarko Gajic that is very worthwhile to go through.
For the best "visual" introduction, see Nick Hodges' Thirty Camtasia Demos in Thirty Days. It is for Turbo Delphi which no longer is offered, but is still very similar to full Delphi and lets you visually get a feel for how to do things in Delphi.
Where you put things depends on what they do. The unit associated with a form should really only contain code that's directly related to the user interface that the form presents. Putting business logic directly into a form unit is considered bad practice for a number of reasons. If your utility methods aren't part of a specific form, it's best to put them in a Unit.
As for Data Modules, they're containers for holding non-visual controls. As the name implies, they were created for database access, but they can hold all sorts of other things. For example, at work we have a handful of data modules that contain TImageList controls, which hold lists of icons that are used in various places throughout the app. If you have any non-visual controls that you need to share with several different forms, a Data Module is the logical place to put them.
And yeah, it looks like you're doing the customized form right. If you have a second form that the first form needs access to, (to make it show up when you hit a button or menu item, for example,) then the first form's unit will need the second form's unit in its uses clause. (There are ways around this involving class registration techniques, but that's an advanced topic.)
You might want to avoid using the global form variable that Delphi likes to set up in a form unit, though. It makes your program start up more slowly, and using globals is another thing that's considered a bad practice. A form is an object like any other Delphi object, and you can create it with its constructor, call Show or ShowModal to make it appear, and then call Release or Free on it (read up on TForm.Release in the helpfile to know when you need to use it) when you're done with it.
For starters, create a few different units based on categories - StringUtils.pas, MathUtils.pas, DateTimeUtils.pas, etc - put your functions into those units according to category and be sure to include all the prototypes in your interface section so they'll be visible to other units (but don't get too caught up in how to categorize things...) and keep all your util units in a separate, dedicated directory. Then, point your Delphi or Project library paths to that directory and you'll be able to use the functions in all your utility units. Eventually, you may want to make the units into classes with class functions or persistent structures etc. I myself generally create a project group that includes a package called MyProjectUtils.bpl and I put all my utility units and classes into that package. I never actually deploy it as a package, but since they are wrapped up together I can always check that they all compile properly and they are all available immediately for browsing in the IDE, etc.