× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.




1. Suppose I write a service program with 4 modules inside it. Consider that 100 other programmers are using the service program. Suddenly I make some changes to one of the modules in the service program. Just imagine what will happen to all those programs, which uses this service program. Maybe they didn't want that change to happen. They will get unexpected results because of the change I made to the service program, without their knowledge. They actually don't want some unexpected results but they will be getting it because I have done some changes.

That's not any different than changing a file in a way that causes programs to break. Or changing the parameters to a program. Or changing a command...


There are lots of ways that you can choose to break backward compatibility if you want. And all of them are bad. While it's possible to do these things, you should try to avoid them!

With service programs you're given better tools to help you avoid breaking backward compatibility.

Instead of changing an existing subprocedure, you can add a new one. Old programs will continue to work, while new ones will be able to take advantage of the new interface. You can't do that with programs. You can't do that with files. Only with service programs!

If you do need to break backward compatibility (though, you should never have to!) you can change the signature on your service program so that existing programs will get an error if they're not upgraded. This is similar to a level check error on a file -- and protects you in a similar way. Again, you can't do that with a program -- only with a service program!


2. Let us consider there are no service programs. So we just have
modules and procedures. In such a case, won't it be simpler to code a
separate logic inside a separate program instead of coding it inside a
module. You can attain the same results using a program. So why to go
for modules instead of individual programs which can contain the same
piece of reusable code.

You can't obtain a similar result with a program. A program can only have one entry point -- one entry parameter list. A module that's bound by copy can have many such entry points and many parameter lists.


Consider the process of loading an invoice from disk. Maybe you've got a data structure called "invhead" that contains all of the header information for your invoice, and one called "invline" that represents one line item on the invoice. You want to write a service program to read the invoice and populate those data structures... you'd create the following routines:

     invoice_open(), invoice_read(), invoice_close().

These three routines can be placed into a single service program. To read invoice number 1234 into a subfile, you might do the following:

     x = invoice_open(1234: invhead);

     dow (invoice_read(x: invline));
        rrn += 1;
        write subfile;
     enddo;

     invoice_close(x);

Because these three routines are in a single module in a service program, they can share data. invoice_open() can position to the start of a given invoice. invoice_read() can read the next line item from an invoice from a database file, picking up where the last read left off. invoice_close() can close the invoice files when it's done.

How could you do that with a *PGM? You can't, because a program can only have one parameter list. You couldn't do it in many programs, because they wouldn't be able to (easily) share data between them.

Then, maybe a year later, you're asked to change the invoicing *SRVPGM. You need to add new fields to the invline data structure, but you don't want to break compatibility with existing prorgrams. What will you do?

You can create a new subprocedure in the same service program called invoice_read_ext(). Have it accept the new data structure called invlineext, which is an extended version of the invline DS. Now you've created a way to read the additional fields into the invline data structure without breaking compatibility for older programs.

The only problem now is that you've got two different routines that read an invoice, and it might be a pain to maintain it in two places. So, you change invoice_read() so that it actually calls invoice_read_ext() under the covers to do the reading. It converts the invlineext data structure into an invline data structure before returning it to the original program.

Now you've maintained backward compatibility, and added the new features that you need, AND you've only got one place to maintain the code.

You can't do that with a *PGM. You can't do it with subroutines. You COULD do it with a bind-by-copy module, but you'd have to recompile every program that used it -- which would also mean that you'd have to re-test every program that uses it.

The advantages of service programs may not seem obvious to you at first, but after you've learned to use them properly, and after you've done it for awhile, you'll be saying "How did I ever get by without this?"

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.