On the subject of bringing old code up to snuff.

Well structured code has good interfaces between sections, hiding detail. The responsibility of a section and its underlying assumptions is understood in terms of it's interface and accompanying documentation. (OK, yes, abstractions are partially leaky in practice, but to the extent that they aren't, you win).

Where you lack this, you need to read and attempt to understand much more code to get the picture of what is going on.

One way you can evolve a codebase is to try and identify candidates for such interfaces (configuration and logging are often a good place to start). If you find somewhere where you can seperate off a chunk of functionality behind a decent interface, you can write your new interface in terms of the old functionality, i.e. you can proxy back to the existing (proven) code whilst gaining the benefit of having clearer expression of intent in your newer code.

You can document and unit test these interfaces, etc and get benefits that way.

Over time, as you touch older code, you might migrate it over to the new interface, reducing the amount of code which depends on the old codebase directly.

Possibly, you could re-implement the interface in terms of new, clean code (relying on your tests to see if you've broken anything). You can then either ditch the old code (if no-one else is using it) or proxy the old methods onto the new code if possible.

So, I think a large part of design (including retro-fitted design) is coming up with good interfaces between sections of code. The above is one way of retro-fitting such design on existing code.

Also - IMHO an interface should provide the least functionality you can get away with for the task at hand. If you have an internal function (_foo) which you think might be handy to make public, resist the temptation - the smaller the interface the easier it is to understand.

If you do want that function in the interface in the future, it's easy enough to rename (because it's only used internally in that module). The reverse isn't true. Taking a method private (say because you want to change an internal algorithm) is much harder - you have to find and change all occurences of the code which uses it (or come up with a reasonable way to fake it in the new implementation).


In reply to Re: Advisability of circular dependencies in packages by jbert
in thread Advisability of circular dependencies in packages by throop

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.