-2

I have a small software that generates some Word documents. It reads a template, runs a few SqL procedures to get the data, generates the documents and then sends them via e-mail. It's quite simple.

Right now I want to apply that logic to generate another type of report, the base word template will change and it will run different queries. I can do this (wrongly) by copy pasting the code, but I want to extend the current app to generate both reports.

What I can't figure out is what software pattern I need to apply to solve this situation.

4
  • 1
    have you considered the use of functions? or procedures?
    – AK_
    Nov 27, 2015 at 17:41
  • 4
    Searching for patterns is not the correct approach. Nov 27, 2015 at 18:14
  • 1
    What you are looking for is SOLID: Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion. en.m.wikipedia.org/wiki/SOLID_(object-oriented_design) Nov 27, 2015 at 20:34
  • "I have a small software that generates some Word documents. It reads a template, runs a few SqL procedures to get the data, generates the documents and then sends them via e-mail. It's quite simple". You might start with two procedures: generate_document(template) takes a template and returns a document and SendDoc(document, email) which takes a document and sends it to the given email address. I like to imagine the procedures to only involve things the users care about. So for example, SQL is not mentioned in the interface because the users probably don't care about that detail.
    – Brandin
    Dec 1, 2015 at 10:38

2 Answers 2

4

The usual way is to refactor the common functionality into its own method or class, and then call that method or class from those two places, passing the required information to the class through its method or constructor parameters.

See Also
Refactoring on Wikipedia

1
0

To add to what @Robert says, I think of this as seeking a parameterization technique that allows the common code to be written once (so it can be maintained in one place) and then reused instead of pasting.

However, you have to determine the kind of parameterization that will let you factor the common part to be written just once.

Often function parameters suffice, but that's not the only approach.

There are also classes and methods as @Robert says. Sometimes we use overrides and/or interfaces: I think of overrides and interfaces as a form of parameterization: The use of base class or interface serves to express a bundle of formal parameters and the concrete subclass or interface implementation serves binding of the bundle of actual parameters.

Don't forget that in many (esp. functional) languages we can have higher-order functions, meaning functions can take parameters that refer to functions, which enables other use cases. Abstract and interface methods act a lot like function parameters, perhaps with a bit more structure.

Another tool that some languages provide is generic types. Sometimes common code cannot be expressed with normal parameters: what differs between scenarios is the types being operated over, even if the code is the same in any case. In those situations generics help.

You can discuss some design pattern in terms of parameterization, such as a Observer and Visitor pattern, which abstracts specific data structure or its traversal from an action to be performed. These can be implemented by OOP techniques (using overrides or interfaces) and also by higher-order functions.

And still, other techniques (monads) allow other kinds of common code to be collected so as to be written only once. There is ongoing research in other kinds of parameterization.

In general, though, I think one can make a mental link of many of the techniques to reduce copied (pasted) code to variations on parameterization.

Not the answer you're looking for? Browse other questions tagged or ask your own question.