Jump to content
Mike Torrettinni

How do you organize developing new features in big projects?

Recommended Posts

Without looking at something specific, it's hard to comment on this. I think the version control thing is off-topic, but I get how people see it.

 

What I'm hearing in this question is "how do you handle design evolution?"

 

I typically start a new project with a general idea that begins with a single form and unit. It's not like I sit down and map everything out first, although sometimes I do. Many times I use Delphi as a prototyping tool, so I'll lay down different ideas in different "apps" just to see how it "feels" from different starting points.

 

Also, if there are different specific "functional units" (I use the term loosely) then I might flesh them out as separate little apps, but build them in a way that the main form acts as a stub to drive the main logic in a separate unit. Sometimes it all starts out in one unit, then I migrate a chunk out into a separate unit that can stand alone. FWIW, in general it's not possible to use a "main form" to build something you want to add to another app. There are things needed in a "main form" that are never found in standalone forms, so if you know you want to build a form that's going to be used in another app, start with two forms: the main form and a second one where you'll explore your new idea. In many such cases, the main form is just a form with a button "Open Form2" or whatever. You set up context in the main form, then call the new one you're developing.

 

That said, I'll often add new stuff to the main form until it begins to take on a clear shape, then move that code into a separate unit, either as a separate (non-visual) class or a separate (visual) form, depending on the need.

 

For apps that have lots of forms, your main form becomes more like a launch pad for everything else, like the foundation of a house. Part of it may end up acting like a traffic cop, using different forms / units to support each menu event. If you have to support "settings", you'll typically manage them in the main form somehow, but it's best to keep them in a separate class / object instance that can be passed around rather than having other units just reaching into the main form for stuff (causing circular references). Sometimes it helps to pass a reference to the settings object to new forms as a common input parameter when they're created rather than a litany of separate variables. (Eg, input_folder, temp_folder, output_folder, input_fname, output_fname, username, userid, permissions_level, blah blah blah...)

 

Settings are also commonly saved in an INI file or in the Registry rather than a standalone "settings" object. That means that if you want to ensure reduced coupling between units, you'll pass in the name of the INI file or Registry keys when the form is created. Again, people frequently get sloppy here and since the programmer "just knows" these details, the code becomes littered with unconstrained accesses to INI or Registry data that can lead to headaches down the road. It's best to create a wrapper class around whatever you use so if you decide to move it from say an INI file to the Registry, then perhaps into a DB, you only need to change it in one place. 

 

(The place I'm working now has such strict security crap in place that we developers cannot even run RegEdit! We can get limited access through a wrapper, but things like Delphi's settings are considered "sensitive" and we can't get access to them! Our programmers are returning to using INI files for small localized stuff, and use the DB for more extensive and production-related needs. Existing code needs to be migrated to bypass the Registry, and it's no small feat when there are dozens of direct accesses to Registry entries scattered throughout the code base. If these were all put into a single TAppSettings class from the outset, we'd simply need to change a couple of local methods and viola! Everything would be switched over.)

 

I'll frequently start out putting common functions in the main form, but at some point they get moved into a separate unit to avoid circular references.

 

It helps to remember that "forms are classes" and the same rules that apply to classes apply to forms, although it has been common for people to forget that and they end up with quite a mess as their project grows. I think of forms as "visual classes" and treat them the same as any other class: you need to instantiate them, set up initial values, fire of their main "do_something" method(s), get back results, and then dispose of them. Maybe you decide to have them created automatically at start-up and leave them "open" all the time, but that can be dangerous and leads to lazy coding practices. Treat them the same way you treat classes and your life will be much easier as your app grows.

 

Does this address any of your concerns? Or am I totally off-base?

Edited by David Schwartz

Share this post


Link to post

Thank you, David, this was very detailed. I am very well aware how these open debates go, their usefulness and that sometimes is hard to imagine what or why I'm asking, but I would not waste everybody's time if it wasn't something I really question myself about.

If you look at some of my questions, you will see a lot has to do about the actual practical application and not theory, as you can read in books. As a single developer, it's often hard to imagine how other developers develop, and one way is with these questions, where I try to imagine every comment how it works out in practice. This is something that, I imagine, makes very little sense to developers who work (or have learned to develop) in teams and have support available within the team - and a lot of times the most useful suggestions come from exactly these developers from teams, because their 'mistakes' have already been noticed and pointed out by others.

So, I appreciate every comment.

 

OK, back on topic. Your details give me another point of view, especially:

38 minutes ago, David Schwartz said:

It helps to remember that "forms are classes" and the same rules that apply to classes apply to forms,

this is true for Frames, for Forms I'm still a little bit hesitant to see them as flexible as Frames.

Share this post


Link to post

Deleted. Post went to the wrong place...?

Edited by aehimself

Share this post


Link to post

Hi...:classic_cool:

Even if you are the only developer, you should have a ticket system. You can use it to create small "building blocks" for the project. Think of it as a "to-do" list, where you document which changes have been made for the one ticket. :classic_tongue:

A small one is Mantis. https://www.mantisbt.org/

image.thumb.png.f77ad56f6de3038bb0cd54baf10de186.pngimage.thumb.png.411a5d4b17715a02b35a348ec71a7774.pngimage.thumb.png.e390f8a8a01df8e2491b1b5f6002b477.png

Edited by haentschman
  • Like 1

Share this post


Link to post
12 hours ago, Mike Torrettinni said:

Thank you, David, this was very detailed. I am very well aware how these open debates go, their usefulness and that sometimes is hard to imagine what or why I'm asking, but I would not waste everybody's time if it wasn't something I really question myself about.

If you look at some of my questions, you will see a lot has to do about the actual practical application and not theory, as you can read in books. As a single developer, it's often hard to imagine how other developers develop, and one way is with these questions, where I try to imagine every comment how it works out in practice. This is something that, I imagine, makes very little sense to developers who work (or have learned to develop) in teams and have support available within the team - and a lot of times the most useful suggestions come from exactly these developers from teams, because their 'mistakes' have already been noticed and pointed out by others.

So, I appreciate every comment.

 

I get more Delphi-specific help online than I get from work colleagues. Have for years. That's the trouble in this business. I get hired because I'm supposedly a "Delphi expert" and they assign me to work with someone who teaches me how to use the crap process they have not changed in 10+ years because "the new guy doesn't know what he's doing yet".

 

I make suggestions, and after a while someone pulls me aside and says I really need to "get with the program" and stop coming up with ideas about how to improve things and start learning the way the system works today ... because it's WORKING.

 

Yup ... mostly ... except for the random errors and the blue-screens and the high-frequency of customer-generated errors that make our apps blow up ... 

 

My boss told me recently that I need to not be so afraid to debug stuff, that I need to roll up my sleeves and spend however many hours it takes working with the debugger to find input errors in an import parser. Our customers send us data files with a hundreds of thousands of de-normalized database records in CSV format, and sometimes they leave a new field name off the end of the header; or their system decides to render fields that are not usually zero as <empty>, as in xxx,,yyy,zzz... -- see it there between xxx and yyy? It just jumps right out atcha, don't it? This is the "New and Improved 2020 Digital Millennium Edition of Where's Waldo?" Waldo is hiding between those double-commas!

 

Our code is fairly brittle and we get lots of error reports daily saying the Delphi apps crashed. The problem is that there are a ton of places in the import routines that call things like StrToInt(...) that throw exceptions when an input token is empty or not a numeric value. None of the fields are validated before we try the conversions, and our code doesn't have ANY Try...Except fencing around it anywhere. So all the exceptions get raised to the outermost layer of our framework that just re-raises them. My boss wanted me to get on a screen-share session with another developer to "see how it's done". The other guy said it took him about 90 minutes to track down the problem.

 

Thankfully, I was busy on something else that had higher priority. When I was done with my work, I fired up Delphi, enabled madExcept, ran the same import routine and data, and found the errant line in less than 90 seconds. I made a short video of it with SnagIt and posted it for them. A company license for madExcept is less than it costs us to track down four or five of these import bugs, and we get one or two of them every week from clients.

 

I'm trying to be helpful and show them how to waste less time, but of course they see it like I'm spitting in their faces. People are so effing weird...

 

So don't think you're missing anything by working alone. Most of the folks in this forum can answer questions nobody else can. They get tired of me asking what must seem like dumb or repetitive questions, but that's another matter. It's better than asking colleagues who don't even understand what I'm asking or insist I forget all of that "expertise" they hired me for so I don't make them all look so ignorant.

 

Anyway, I can't tell if what I posted was helpful since you went off on a meta-discussion...

 

Quote

OK, back on topic. Your details give me another point of view, especially:

this is true for Frames, for Forms I'm still a little bit hesitant to see them as flexible as Frames.

As for this comment ... I think you're missing the point entirely.

TMyClass = class
. . .
end;

This is a class. It has nothing whatever to do with frames.

TMyForm = class(TForm)
. . .
end;

This is also a class. It also has nothing whatever to do with frames.

 

As far as "flexibility" goes ... they're CLASSES ... you can make them do ANYTHING you want!

 

Frames are also classes. So what? So are TStringLists. 

 

You're confusing language constructs with magic pixie dust that the IDE provides you in a few random cases. I've seen Frames implemented without help from the IDE and they are butt-ugly and not half as useful.

 

I'm talking about CLASSES... some of which are derived from TForm.

 

The way you interact with TMyForm should be no different than how you interact with TMyClass. That's all I'm saying.

 

People nod their head as if they agree. But they don't. Not really.

 

Most Delphi devs will happily go on and on about the proper ways of interacting with classes (in general), and then proceed to throw most of that lecture out the window when it comes to interacting with Forms.

 

Go figure...

 

 

  • Like 1

Share this post


Link to post

VCS branches are good when a feature is tied to project. When it's a new concept or some new class, I prefer to create and test it in new standalone project thus not carrying the burden of a whole big project (build time, long code, excess actions etc). My old-school colleague is testing all features on a main app which takes ~1 min to build and ~5-6 mouse actions to reach functionality he is testing. I wonder how he hadn't go crazy yet %-)

Edited by Fr0sT.Brutal

Share this post


Link to post

I can't really understand why people keep going on about version control stuff when the author has stated it's off-topic.... he seems to be asking about DESIGN approaches, like, eg., when you realize you need to split a class up into multiple pieces, not how to manage source code.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×