Skip to main content
Removed buzzword "design pattern" from the question
Source Link
Doc Brown
  • 214k
  • 34
  • 394
  • 603

Design Patterns For Rewriting Approach for rewriting a Largelarge, Missionmission-Critical Methodcritical method

Context: I am a new hire out of university at a large software company tasked with either refactoring or re-writing a large legacy method (~500 lines, ~2000 lines expanded with private method calls) that performs a complex workflow with many responsibilities. You can imagine it applying a complex series of interdependent transformations to its input before returning the transformed data. Static code analysis indicates it has a cyclomatic complexity of 67. This class is part of a package used across multiple services not owned by my team and as such the interface cannot be modified. This method is part of a package that is being deprecated feature-by-feature over a long period of time. The goal of the refactor/rewrite is to make it so that we maintain feature parity with the original implementation, but can easily disable individual transformations over time. The method has few tests, so my first task will be to create a full test suite for the class to enforce stable behavior.

What sort of design patternsapproach can I apply in order to successfully perform this refactor? My current idea is some sort of Pipeline pattern where we take a collection of enums which describe which transformations to disable when assembling the pipeline. This way deprecating transformations in the future is a matter of adding an additional enum to the parameter. E.g. Something along the lines of

public class LegacyClass {
...
    public WorkflowResponse performWorkflow(WorkflowInput workflowInput) {
        WorkflowPipeline pipeline = this.assemblePipeline(this.featureDeprecations);
        pipeline.validate();
        return pipeline.execute();
    }

    private WorkflowPipeline assemblePipeline(EnumSet<FeatureDeprecations> featureDeprecations) {
        WorkflowPipeline pipeline = new WorkflowPipeline();
        pipeline.addTransformation(new TransformationOne());
        if(!featureDeprecations.contains(DEPRECATE_TRANSFORMATION_TWO)) {
            pipeline.addTransformation(new TransformationTwo());
        }
        pipeline.addTransformation(new TransformationThree());
        return pipeline;
    }

Is following this design patternapproach a good idea for my situation? The main downside I can see is that the code for assembling the pipeline will grow to be very complex even if I manage to encapsulate each transformation rather than having them live within the performWorkflow method.

Design Patterns For Rewriting a Large, Mission-Critical Method

Context: I am a new hire out of university at a large software company tasked with either refactoring or re-writing a large legacy method (~500 lines, ~2000 lines expanded with private method calls) that performs a complex workflow with many responsibilities. You can imagine it applying a complex series of interdependent transformations to its input before returning the transformed data. Static code analysis indicates it has a cyclomatic complexity of 67. This class is part of a package used across multiple services not owned by my team and as such the interface cannot be modified. This method is part of a package that is being deprecated feature-by-feature over a long period of time. The goal of the refactor/rewrite is to make it so that we maintain feature parity with the original implementation, but can easily disable individual transformations over time. The method has few tests, so my first task will be to create a full test suite for the class to enforce stable behavior.

What sort of design patterns can I apply in order to successfully perform this refactor? My current idea is some sort of Pipeline pattern where we take a collection of enums which describe which transformations to disable when assembling the pipeline. This way deprecating transformations in the future is a matter of adding an additional enum to the parameter. E.g. Something along the lines of

public class LegacyClass {
...
    public WorkflowResponse performWorkflow(WorkflowInput workflowInput) {
        WorkflowPipeline pipeline = this.assemblePipeline(this.featureDeprecations);
        pipeline.validate();
        return pipeline.execute();
    }

    private WorkflowPipeline assemblePipeline(EnumSet<FeatureDeprecations> featureDeprecations) {
        WorkflowPipeline pipeline = new WorkflowPipeline();
        pipeline.addTransformation(new TransformationOne());
        if(!featureDeprecations.contains(DEPRECATE_TRANSFORMATION_TWO)) {
            pipeline.addTransformation(new TransformationTwo());
        }
        pipeline.addTransformation(new TransformationThree());
        return pipeline;
    }

Is following this design pattern a good idea for my situation? The main downside I can see is that the code for assembling the pipeline will grow to be very complex even if I manage to encapsulate each transformation rather than having them live within the performWorkflow method.

Approach for rewriting a large, mission-critical method

Context: I am a new hire out of university at a large software company tasked with either refactoring or re-writing a large legacy method (~500 lines, ~2000 lines expanded with private method calls) that performs a complex workflow with many responsibilities. You can imagine it applying a complex series of interdependent transformations to its input before returning the transformed data. Static code analysis indicates it has a cyclomatic complexity of 67. This class is part of a package used across multiple services not owned by my team and as such the interface cannot be modified. This method is part of a package that is being deprecated feature-by-feature over a long period of time. The goal of the refactor/rewrite is to make it so that we maintain feature parity with the original implementation, but can easily disable individual transformations over time. The method has few tests, so my first task will be to create a full test suite for the class to enforce stable behavior.

What sort of approach can I apply in order to successfully perform this refactor? My current idea is some sort of Pipeline where we take a collection of enums which describe which transformations to disable when assembling the pipeline. This way deprecating transformations in the future is a matter of adding an additional enum to the parameter. E.g. Something along the lines of

public class LegacyClass {
...
    public WorkflowResponse performWorkflow(WorkflowInput workflowInput) {
        WorkflowPipeline pipeline = this.assemblePipeline(this.featureDeprecations);
        pipeline.validate();
        return pipeline.execute();
    }

    private WorkflowPipeline assemblePipeline(EnumSet<FeatureDeprecations> featureDeprecations) {
        WorkflowPipeline pipeline = new WorkflowPipeline();
        pipeline.addTransformation(new TransformationOne());
        if(!featureDeprecations.contains(DEPRECATE_TRANSFORMATION_TWO)) {
            pipeline.addTransformation(new TransformationTwo());
        }
        pipeline.addTransformation(new TransformationThree());
        return pipeline;
    }

Is following this approach a good idea for my situation? The main downside I can see is that the code for assembling the pipeline will grow to be very complex even if I manage to encapsulate each transformation rather than having them live within the performWorkflow method.

Post Reopened by Doc Brown design-patterns
Post Closed as "Duplicate" by gnat, Useless, CommunityBot
Source Link
hpabst
  • 133
  • 3

Design Patterns For Rewriting a Large, Mission-Critical Method

Context: I am a new hire out of university at a large software company tasked with either refactoring or re-writing a large legacy method (~500 lines, ~2000 lines expanded with private method calls) that performs a complex workflow with many responsibilities. You can imagine it applying a complex series of interdependent transformations to its input before returning the transformed data. Static code analysis indicates it has a cyclomatic complexity of 67. This class is part of a package used across multiple services not owned by my team and as such the interface cannot be modified. This method is part of a package that is being deprecated feature-by-feature over a long period of time. The goal of the refactor/rewrite is to make it so that we maintain feature parity with the original implementation, but can easily disable individual transformations over time. The method has few tests, so my first task will be to create a full test suite for the class to enforce stable behavior.

What sort of design patterns can I apply in order to successfully perform this refactor? My current idea is some sort of Pipeline pattern where we take a collection of enums which describe which transformations to disable when assembling the pipeline. This way deprecating transformations in the future is a matter of adding an additional enum to the parameter. E.g. Something along the lines of

public class LegacyClass {
...
    public WorkflowResponse performWorkflow(WorkflowInput workflowInput) {
        WorkflowPipeline pipeline = this.assemblePipeline(this.featureDeprecations);
        pipeline.validate();
        return pipeline.execute();
    }

    private WorkflowPipeline assemblePipeline(EnumSet<FeatureDeprecations> featureDeprecations) {
        WorkflowPipeline pipeline = new WorkflowPipeline();
        pipeline.addTransformation(new TransformationOne());
        if(!featureDeprecations.contains(DEPRECATE_TRANSFORMATION_TWO)) {
            pipeline.addTransformation(new TransformationTwo());
        }
        pipeline.addTransformation(new TransformationThree());
        return pipeline;
    }

Is following this design pattern a good idea for my situation? The main downside I can see is that the code for assembling the pipeline will grow to be very complex even if I manage to encapsulate each transformation rather than having them live within the performWorkflow method.