views:

68

answers:

6

Hello there freaks & geeks. Here comes my question again, thanks for helping!.

Lets suppose i have an object Foo, which method foo() does about 100 lines.

foo() { ... qwert yuiop asdfg zxcvb nmhjk ... }

If a developer wants to add some code to foo(), it can be easily done with inheritance, composing or a Decorator Pattern.

But in the case he wants to modify "one line" in the middle of the code (changing a property value, invoking a method before something...), whats the best way to do it?

foo2() { ... qwert yuiop ASDFG zxcvb nmhjk ... }

The goal is to let the original developer to define a behavior without worriying about what others will modify/change.

The new developer should be able to change the object/method/property without retyping the code.

Inserting breaks or predefining steps with callbacks/listeners or dividing the code into smaller pieces is not the desired option, cause it involves the first developer, which is sleeping. :P

What about a commit environment where the changes made to the object need a commit to apply? foo() does normal, then foo2 just change the desired properties and make commit.

Any other alternatives?

Thanks!

A: 

Depending on what the function a() does, I would probably make an optional parameter to a() that takes a function that is run instead of asdf.

Python-ish:

def a(foo=None):
    qert
    yuiop
    if foo is None:
        asdf
    else:
        foo()
    zxcvb
    nmhjk

a(foo=lambda: ASDF)
André Laszlo
Not a good idea, cause you have to rewrite for each change.The goal is to modify the first object from the second:A has a(){asdf}B has b(){ change A behaviour here, but just that 2 lines! }
ESP
Yeah, in general. My guess was that you wanted to change something specific like a comparator or something.
André Laszlo
+1  A: 

Break the function up into smaller steps. Chances are that a 100 line function does more than one thing (and if it doesn't there would't be a need to change a line halfway though).

tdammers
the problem i found with this approach is that i have to "be prepared" for a break at any moment (i dont know what other developers want to do with my object), so the code will become like:dobreak;do;break;i know that breaks can be minimized to some moments, but I'm looking for something made from the redefining object, not designed from the beginning
ESP
@ESP Your classes should have a well designed purpose and shouldn't be (and can't be) jacks-of-all-trades. Ask the other programmer what he needs it for, define some requirements and write it against these.
pmr
Indeed. You cannot (and shouldn't) cater for changes at any given point in your method. Instead, break it down into logical chunks (say, 10 to 20 lines each), each an 'atomic' processing step where doing things in between wouldn't make sense. You may need more than one level of abstraction to achieve this, but once you do, other programmers can simply insert their own code by overriding one of your subroutines and adding their own code before or after calling the original one.
tdammers
What about a commit environment where a() does everything except "commit", and B modify, change, rollback whatever and then does commit and changes are applied?
ESP
A: 

Encapsulate steps that change the behaviour of the object. In C++ land policy-based design is often used if you don't need to decide on the behaviour at run-time. The control-flow is defined in the class and what is actually done at some points depends on the template parameters.

The important and hardest part is to split up your methods accordingly and often depends on the customizability that you require. Keep YAGNI in mind when doing something like this.

pmr
Keeping YAGNI in mind, inserting breaks doesn't seem correct, at least, not very pretty.i ask koen another approach, using a "commit environment".
ESP
A: 

Depending on what the other developer needs to insert, this may be a candidate to introduce hooks in your system using an observer pattern.

koen
The other developer needs to add properties, methods and change some values.In fact the question of "when to add/edit them" seems only possible with predefined breaks/hooks/steps, but i cannot be prepared for everything.do you consider a better option to do all the code without committing and then try to rollback/modify something specific?
ESP
@ESP I'm confused in how this all should work. From your reply here I understand that you will leave your code on some central location, when you're gone other developers will work on it, and when you're back you need to start from where you left it. Is that the workflow?
koen
A: 

But in the case he wants to modify "one line" in the middle of the code (changing a property, invoking a new function before something...), decorator it is not an option.

What do you think is the correct approach to achieve this?(modify 2 lines of 100 without retyping all)

Retyping the lines of code is not the issue, because the chances are it will be just a copy&paste. You need to eliminate code duplication. So make you function overrideable (so the next developer can inherit from it or extend it), and factor out all the common code into smaller separate functions.

If you are using .Net then you could also consider refactoring the function to accept a delegate or lambda as one of its parameters, and that delegate/lambda gets executed at the critical spot (this may be your best option). You may also be able to achieve your aim with partial classes - you write some of the code of the class, the other developer writes the rest, although this may be a messy solution for your problem.

Should i design a() with 100 listeners/callbacks? Should i define some "known steps" and use something like "insertCodeBefore/After(step)"?

This is likely to also be a very messy and inefficient solution.

slugster
I agree with you with the messy and inefficient solution.In the other hand, splitting my class into classes or methods can reduce code duplicity, but increase complexity and seems to be the same problem: What if a piece of code, already on a partial class, need to be changed again?The goal here is trying to change some lines/behavior in the "new class", without worrying what's on the first.
ESP
@ESP - then you are probably left with using virtual/abstract methods and overriding functionality in a child class (still staying reasonably language agnostic). Splitting out code into smaller functions may seem like adding complexity but it isn't, it also reduces the scope of any future changes that need to be made.
slugster
I understand what u say, but the goal is to code and don't care about what others will add/edit...i know that can be done with that, but I'm looking for a more flexible/idontcarewhatothersdo way.
ESP
A: 

@Koen yes...its more or less what i want.

I code my part, u code yours, but can use part of mine.

Its not the objetive, buts looks like the workflow.

ESP