Are there some Delphi specific issues with "One class per file" rule? [closed]
Asked Answered
I

3

7

Old title: How many classes per unit are advisable to have?

My question is specific to Delphi. I think that in Java and C# world it is a rather accepted practice to generally have one file per class. I think this is a good rule to follow in Delphi too, because in Delphi private members aren't really private if you have more than one class in a unit.

So I was surprised to hear from two different senior (and probably more experienced than I am) programmers tell me I divide my code too much. One of them told me to not be shy about placing 5-6 classes in a unit.

Is there some issue with "one class per module" rule that I am not aware of, that could warrant and explain the reactions of these programmers?

Itch answered 21/7, 2012 at 14:34 Comment(3)
The problem with Delphi is that the file name doubles as namespace. Having one to important that many units is annoying.Strudel
Interesting question, although not a good fit for SO. Take a look at the RTL/VCL units of Delphi its self, for example, Vcl.Controls. Tons of classes. But then look at the Indy system - they do seem to follow the one class per unit concept. That being said, it's really a matter of opinion, and how you're most comfortable.Homeroom
⦁ Multiple (barelly related) classes in one file -> leads to: ⦁ Abbusive use of "strict" keyword. ⦁ Jump like crazy to the code to find the place I want to edit. ⦁ Bad overview of the unit. ⦁ Unnecessary compilation of the whole unit. ⦁ Help us see where the code/classes are too much interconnected ⦁ Use "Unit Cleaner" to remove unnecessary code/classes ⦁ Clarification: I am not saying one class per unit. I am saying one big class OR one dedicated class per unit.Quinn
R
2

I don't know what you mean by module.

Java requires one public class per file, and the class name must match the file name. No ifs, ands, or buts. You can have other package private or private methods in that file, but only one public class.

If "module" means "package" to you, then I'd say it's common to have more than one class in a package. There's no norm; have a look at the JDK itself to see that. There are many classes in java.util, java.lang, java.sql, and javax.swing.

Besides those two, I have no idea what you or the alleged "senior programmers" are referring to. I would agree that it's possible to do anything to excess, and dogmatic rules should not be followed blindly.

But decomposition is a computer science -no, a problem solving - fundamental. It's more common to neglect it than to overdo it.

Roselane answered 21/7, 2012 at 14:39 Comment(4)
By module I mean file. In Delphi they are called units.Itch
Then I disagree with your "senior programmers". It's commonly one class per file for me. I'd ask what the benefit of cutting down the number of files is? A 1:1 relationship lets me gauge the size of the project just by looking at the file count. Combining them forces me to look inside. What's the benefit?Roselane
@duffymo, may be it is common to you, but it is rarely seen in the Delphi eco-system. Just as one file per project is an extreme (even if it is possible sometimes), so one file per class is just the other extreme. While Java seems to just require it, Delphi gives you the freedom to decide yourself. More than that, Delphi even allows no class in a file.Secondly
Yeah, I suspected this is rarely seen in the Delphi world, and I wondered why. I didn't know it was required in Java. I thought it was just considered a good practice. But then, if it is a requirement, then it probably is indeed considered a good practice, at least by Java designers?Itch
H
2

It depends. There is no an exact rule to follow. Usually you need to grup classes in units by logical, common dependency or better to understand business functionality.

For example, if you have a lot of small helper, adiacent, complementary classes there is a reason to put all of them in a single unit. Like Borland did in DB.pas unit. All general DB stuff there: TDataSet, TDataSource, TField etc...

Forms, ie TForm descendants Borland recommends one per unit, because of dfm resource loading etc...

Usually when you write "uses FOO;" means that compiler include all stuff from FOO. You can access classes, consts, types etc... So, it's good to divide but keeping rationality.

In latest versions of Delphi units are treated as namespaces. You can better organize your code.

Holliman answered 21/7, 2012 at 15:4 Comment(1)
Even one file per TForm doesn't mean that this file cannot contain other classes.Secondly
T
0

One class per unit is too strict. Sometimes classes are related so they can be joined in a single unit.

The problem with the backdoor for protected and private variables can be fixed by using the strict directive:

type
  TClass1 = class 
  private
    FField1 : Integer;
  strict private
    FField2 : Integer;
  end;

  TClass2 = class 
  public
    procedure MessWithClass1;
  end;



implementation
  procedure TClass2.MessWithClass1;
  var
    c1 : TClass1;
  begin
    c1.FField1 := 1;
    c1.FField2 := 2;   // Fails!
  end;     
Tallage answered 21/7, 2012 at 15:6 Comment(1)
Yes, I agree about the related classes. About strict directive - it was introduced after Delphi 7, unfortunately.Itch

© 2022 - 2024 — McMap. All rights reserved.