Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 10 total
Thread Alternatives to IFDEF
Sun, Feb 7 2016 4:16 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

I'm trying to alter my email subsystem so I can use it in different applications. There are only two at the moment but there will be some more. When I started I was only thinking in terms of two of them so I've been "happily" IFDEFing things. It works but even with just the two different applications its starting to look messy. My current thought is to modify the code to create base forms/threads etc with virtual stubs then can be overwritten in descendents and move as much as possible to sql to make it easier to code with different tables and table structures.

Before I commit to this I'd be interested in what others think or have done.


Roy Lambert
Mon, Feb 8 2016 4:04 AMPermanent Link

Matthew Jones

Roy Lambert wrote:

> I'm trying to alter my email subsystem so I can use it in different
> applications. There are only two at the moment but there will be some
> more. ...

I have way too much experience of this. I'll have to go back to the
therapist after this response. 8-)

Basically, all options make sense depending on where you are and where
you are going. The easiest is the $IFDEF with different project files,
perhaps in a project group. For example, one thing I'm doing for a
client right now has extra facilities, and so those are done using a
common form with the extras on, and the IFDEF (defined in a project for
one EXE, not in another) controls whether the code removes the
components from the display completely, and the project includes extra
modules for the added functionality. The separation is simple.

I also have things like licence code entry forms which are common
across many projects, but which have IFDEFs to control the method of
code storage or passing.

And in the most fun application, fortunately now on its way out, there
were about 5 different applications, each with a large number of visual
form inheritance and frames. Frames are particularly fun in inherited
forms, and you have to be really careful. I recommend avoiding these
variations if possible.

I have also done the "separate on change" strategy, when I'm going to
be making significant changes. Sometimes I will merge things back later.

In summary, I don't think there is a "winning" or "best" option. I
think a single level of IFDEF is ideal, but that can sometimes be a
matter of choosing the conditional name properly. So not "IFDEF
PRODUCT_A" but "IFDEF SUPPORTS_EDB". Then it works with all 14 products
that use EDB, not just product A. It isn't hard to use in a new product
because it will fail to compile, you add the define, and it works.

I hope this helps!


--

Matthew Jones
Mon, Feb 8 2016 4:36 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Matthew


Thanks for that, especially the bit about frames.

I've started down this route because waaaay back I had two apps using email and I just copied the code from the first to use in the second and then spent years trying to remember when I made a change in one to do it to the other - differences not major but made it awkward.

Its a shame there isn't a best strategy Frown

Roy Lambert
Mon, Feb 8 2016 9:58 AMPermanent Link

Raul

Team Elevate Team Elevate

On 2/7/2016 4:16 AM, Roy Lambert wrote:
> I'm trying to alter my email subsystem so I can use it in different applications. There are only two at the moment but there will be some more. When I started I was only thinking in terms of two of them so I've been "happily" IFDEFing things. It works but even with just the two different applications its starting to look messy. My current thought is to modify the code to create base forms/threads etc with virtual stubs then can be overwritten in descendents and move as much as possible to sql to make it easier to code with different tables and table structures.
> Before I commit to this I'd be interested in what others think or have done.

It really depends on your application and what kind of code you share.

We have very much gone the way of inheritance and declaring lot of
virtual stubs and such. It works really well for us.

Note that this in some cases means that final class in the individual
app is actually unique - though derived thru the common parent classes.
However the local changes in many cases are quite light compared to all
the heavy lifting underneath (often things like final presentation
aspects - showing/hiding fields or renaming on grid - and actual actions
that don't make sense in base classes since they are one-offs).

We still use IFDEFs but those in general are for major architectural
aspects - one place we use it for example is that we share lot of front
and back-end code so some of the functions are IFDEF'd based on whether
we compile a back end server or front end client. Same function call but
some of the code just does not even get included. Other IFDEFs are for
delphi versions (very few in our case) and some licensing stuff for
different editions (we prefer to IFDEF so the feature is not even
present in edition it does not belong to).

Raul

Mon, Feb 8 2016 1:19 PMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Raul


>Note that this in some cases means that final class in the individual
>app is actually unique - though derived thru the common parent classes.
>However the local changes in many cases are quite light compared to all
>the heavy lifting underneath (often things like final presentation
>aspects - showing/hiding fields or renaming on grid - and actual actions
>that don't make sense in base classes since they are one-offs).

I like this idea - I think its just about the amount of work I need to do Frown

>We still use IFDEFs but those in general are for major architectural
>aspects - one place we use it for example is that we share lot of front
>and back-end code so some of the functions are IFDEF'd based on whether
>we compile a back end server or front end client. Same function call but
>some of the code just does not even get included. Other IFDEFs are for
>delphi versions (very few in our case) and some licensing stuff for
>different editions (we prefer to IFDEF so the feature is not even
>present in edition it does not belong to).

I do that as well - much better for the code not to be there rather than not activated

Roy
Tue, Feb 9 2016 4:35 AMPermanent Link

Matthew Jones

Raul wrote:

> We have very much gone the way of inheritance and declaring lot of
> virtual stubs and such. It works really well for us.

That reminds me of another option, which is that the code takes
properties which control behaviour. So in application A, it sets
"DynamicMode" true, and application B sets it false. (Contrived, of
course, but you know what I mean.)

--

Matthew Jones
Tue, Feb 9 2016 5:10 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Matthew

>That reminds me of another option, which is that the code takes
>properties which control behaviour. So in application A, it sets
>"DynamicMode" true, and application B sets it false. (Contrived, of
>course, but you know what I mean.)

That was pretty much my first thought but I couldn't figure out a way to do it in the uses clause which is why I started IFDEFing

Roy
Tue, Feb 9 2016 8:13 AMPermanent Link

Raul

Team Elevate Team Elevate

On 2/9/2016 4:35 AM, Matthew Jones wrote:
> That reminds me of another option, which is that the code takes
> properties which control behaviour. So in application A, it sets
> "DynamicMode" true, and application B sets it false. (Contrived, of
> course, but you know what I mean.)

It definitely works but I find you now end up with mixed code that does
both modes (and likely some "if DynamicMode then ..." sprinkled throughout).

We'd likely do something like this (contrived as well)

Base class:
TOurBaseClass = class

Then App A might use
TImprovedClass = class(TOurBaseClass)

and B might use
TImprovedDynamicClass = class(TImprovedClass)


Raul
Tue, Feb 9 2016 8:39 AMPermanent Link

Matthew Jones

Raul wrote:

> TImprovedClass = class(TOurBaseClass)

I think the key here is that there is complexity involved. How you hide
that may vary a lot. But it will still be complex.

--

Matthew Jones
Tue, Feb 9 2016 2:21 PMPermanent Link

Raul

Team Elevate Team Elevate

On 2/9/2016 8:39 AM, Matthew Jones wrote:
> I think the key here is that there is complexity involved. How you hide
> that may vary a lot. But it will still be complex.

Absolutely - just saying (in this branch of the discussion) that we have
found the inheritance to work best for us.

Raul
Image