Refactoring: Improving the Design of Existing Code

Author: Martin Fowler, Kent Beck
4.4
All Stack Overflow 117
This Year Stack Overflow 7
This Month Stack Overflow 2

Comments

by anonymous   2017-12-24

At first glance, you could use the "Extract Method" refactoring a couple of times.

This code repeats:

ZMsg msg = new ZMsg();
    msg.add(pendingMessage.getEncodedRecords());
    try {
      // this returns instantly
      return msg.send(liveSocket.get().getSocket());
    } finally {
      msg.destroy();
    }

so make something like private void sendMsg() out of it. This code also repeats

PendingMessage m = new PendingMessage(address, encodedRecords, false);
    cache.put(address, m);
    try {
      if (doSendAsync(m, socket)) {
        return m.waitForAck();
      }
      return false;
    } finally {
      cache.invalidate(address);
    }

so make another method out of it.

In general, there's a classic and excellent book on refactoring https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672

by anonymous   2017-08-20

Well .. step nr.1: read this book. You have time enough for that till September.

Watch following lectures:

These materials should give you some sense of the subject.

As for real first steps, separating the HTML from JavaScript is a nice place to begin. If you know how to do event delegation in javascript - good. If not, look into it.

Then you can move on to fixing the part of page that spews out the HTML. Separate the SQL, add some abstraction, some OOP principles.

If you end up aiming at something MVC-shaped, then this list of links might help a bit.

by anonymous   2017-08-20

for automated software unit tests I would recommend google test. There is a very good q&a on this platform, which you can find here.

Additionally, there is CPPUnitLite, which is developed by the author of "Working Effectively with Legacy Code", Michael Feathers.

I used AutoIt Scripts for testing a MFC application just a little bit, but it was not that easy to maintain them properly and build an effective logging system for failed tests.

However, the unit tests depend heavily on the architecture of your program and the structure of your class - especially the dependencies to other components / classes. So if you already have an existing MFC application, which was not built with unit tests in mind, you probably have to refactor a lot of things. Therefore, I would recommend the mentioned book. You can also use the classic "Refactoring" by Martin Fowler.

by anonymous   2017-08-20

May be you need to use Extract Class. It is common methodology for solving Feature Envy code smell (these are both taken from Martin Fowler's Refactoring).

About the many methods in one class - I reacall that I've read somewhere that the JVM will optimize additionaly your code, will inline methods, etc.

by anonymous   2017-08-20

You can buy a copy of Refactoring: Improving the Design of Existing Code from Martin Fowler, you'll find a lot of things you can do during your refactoring operation.

Plus you can use tools provided by your IDE and others code analyzers such as Findbugs or PMD to detect problems in your code.


Resources :

On the same topic :

by anonymous   2017-08-20

By all means, create the variable. A single variable like that will never, ever be a performance bottleneck, never.

Always favor readability. Performance problems usually appear only in specifics parts of a system. When they arise, and not before measuring those (aka having numbers), you treat them case by case. Never forget: Premature optimization is the root of all evil.

In your specific case, you could go even further and create another variable, explaining the intent of the comparison:

String host = args[0].toLowerCase();
boolean isRunningUnderProduction = host.equals("server");
if (isRunningUnderProduction) {
    System.out.println("SERVER");
}

Much better than a comment. And explains the intent of the code within a glimpse.


A quote from Martin Fowler's Refactoring book:

The interesting thing about performance is that if you analyze most programs, you find that they waste most of their time in a small fraction of the code. If you optimize all the code equally, you end up with 90 percent of the optimizations wasted, because you are optimizing code that isn't run much. The time spent making the program fast, the time lost because of lack of clarity, is all wasted time.

In other words: if your programs are easier to read, they are easier to fix the slow parts, when the time comes (if it comes).

by anonymous   2017-08-20

Is there anything I can do except refactor the code?

No. Refactor the code. No method should be that long. Ever. Write small methods!

Seriously: any IDE there is will guide you through the refactoring, but it needs to be done. You might also want to read Refactoring: Improving the Design of Existing Code for guidance.

by Mitch Wheat   2017-08-20

I would recommended (as others have):

by Morendil   2017-08-20

A good or bad design reveals itself by how well it accomodates unexpected requirements, so I would suggest keeping a stock of potential "game features" handy to inform your design reflexions. Since you're doing this as a learning project you can afford to go crazy.

Arkanoid is a very good choice for this, it offers so many options. Make different bricks score different amounts of points. Make some bricks change the score of other bricks when hit. Make some bricks require multiple hits. Give superpowers to the ball, paddle, or bricks. Vary these powers: one of them makes the ball keyboard-controllable, another makes it transparent, another reverses "gravity", and so on. Make bricks drop objects.

The goal is that when you make such a change, it impacts the minimum possible number of classes and methods. Get a feel for how your design must change to fit this criterion.

Use an IDE that has a Refactoring menu, in particular the move method refactoring. (If you haven't, read the book Refactoring.) Experiment with placing your various methods here and there. Notice what becomes hard to change when the method is placed "wrong", and what becomes easier when you place it elsewhere. Methods are placed right when objects take care of their own state; you can "tell" an object to do something, rather than "ask" it questions about its state and then make decisions based on its answers.

Let's assume that in your design each sprite is an object instance. (You could choose other strategies.) Generally, motion alters the state of a sprite, so the method that describes motion for a particular kind of sprite probably belongs on that sprite's class.

Collision detection is a sensitive part of the code, as it potentially involves checking all possible pairs of sprites. You'll want to distinguish checking for collisions and informing objects of collisions. Your ball object needs to alter its motion on colliding with the paddle, for instance. But the algorithm for detecting collisions in general won't belong on the ball class, since other pairs of objects may collide with consequences that matter to the game.

And so on...

by anonymous   2017-08-20

I've heard we should be preferring Composition over Inheritance.

Generally good advice. But it doesn't mean you should replace them all.

If your subclasses need all of what's in the superclasses and each subclass adds small bits of function, you might be fine to stay with inheritance.

How would it apply to these kind of scenarios where you want to use inheritance to remove duplicated code? Should I refactor the code to use Composition? How?

You can also use composition to remove duplicated code.

The refactoring you're looking for is Replace Inheritance with Delegation. Googling this phrase may find you a few references with more detail than a sample diagram, but you really ought to get the book Refactoring.