To DRY or not to DRY? On avoiding code duplication and retaining cohesion - language-agnostic

I've got a question concerning code duplication and refactoring, hope it's not too general. Say you've got a rather small piece of code (~5 lines) which is a sequence of function invocations that is - not a very low level. This code is repeated in several places, so it would probably be a good idea to extract a method here. However, in this particular example, this new function would suffer from low cohesion (which manifests itself, among others, by having a hard time finding a good name for the function). The reason for that is probably because this repeated code is just a part of a bigger algorithm - and it's difficult to divide it into well named steps.
What would you suggest in such scenario?
Edit:
I wanted to keep the question on a general level, so that more people can potentially find it useful, but obviously it would be best to back it up with some code sample. The example might not be the best one ever (it smells in quite a few ways), but I hope it does its job:
class SocketAction {
private static class AlwaysCreateSessionLoginHandler extends LoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
private static class AutoConnectAnyDeviceLoginHandler extends LoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
if (Server.isUserRegistered(socketAction._sess.getUserLogin())) {
Log.logSysInfo("Session autoconnect - acquiring list of action threads...");
String[] sa = Server.getSessionList(socketAction._sess.getUserID());
Log.logSysInfo("Session autoconnect - list of action threads acquired.");
for (int i = 0; i < sa.length; i += 7) {
socketAction.abandonCommThreads();
Server.attachSocketToSession(sa[i + 1], socketAction._commSendThread.getSock());
return;
}
}
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
private static class OnlyNewSessionLoginHandler extends LoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
socketAction.killOldSessionsForUser();
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
}

Question is too general to really say, but as an exercise:
Suppose you abstract it. Think about what the likely reasons are for wanting to change the resulting 5-line function. Would you want likely make changes that apply to all users, or would you end up having to write a new function that's slightly different from the old one, each time some caller has reason to want a change?
If you would want to change it for all users, it's a viable abstraction. Give it a poor name now, you might think of a better one later.
If you're going to end up splitting this function off into lots of similar versions as your code evolves in future, it's probably not a viable abstraction. You could still write the function, but it's more of a code-saving "helper function" than it is part of your formal model of the problem. This isn't very satisfactory: the repetition of this amount of code is a bit worrying, because it suggests there should be a viable abstraction in there somewhere.
Maybe 4 of the 5 lines could be abstracted out, since they're more cohesive, and the fifth line just so happens to be hanging around with them at the moment. Then you could write 2 new functions: one which is this new abstraction, and the other is just a helper that calls the new function and then executes line 5. One of these functions might then have a longer expected useful life than the other...

To me, the litmus test is: if I need to make a change to this sequence of code in one place, (e.g. add a line, change the order), would I need to make the same change in other locations?
If the answer is yes, then it is a logical, "atomic" entity and should be refactored. If the answer is no, then it's a sequence of operations that happen to work in more than one situation - and if refactored, will likely cause you more trouble in the future.

I was thinking about this lately and I understand exactly what you're getting at. It occurs to me that this is an implementation abstraction more than anything, and is thus more palatable if you can avoid changing an interface. For instance, in C++ I might extract the function into the cpp without touching the header. This somewhat lessens the requirement for the function abstraction to be well-formed and meaningful to the class user since it's invisible to them until they really need it (when adding to the implementation).

For me the operative word is "threshold". Another word for this would probably be "smell".
Things are always in a balance. It sounds like (in this case) like the center of balance is in cohesiveness (cool); and as you've only got a small number of duplicates it's not hard to manage.
If you had some major "event" occur and you went to "1000" duplicates then the balance would have shiftyed and so might you're approach.
To me, a few managable duplicates isn't a signal to refactor (yet); but I'd keep an eye on it.

Inheritance is Your friend!
Don't duplicate code. Even if a single line of code is very long or difficult, refactor it to a separate method with a distinctive name. Think of it like someone who will read Your code in a year. If You name this function "blabla", will the next guy know what this function does without reading it's code? If not, You need to change the name. After a week of thinking like that You'll get used to it and Your code will be 12% more readable! ;)
class SocketAction {
private static abstract class CreateSessionLoginHandler extends LoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
private static class AlwaysCreateSessionLoginHandler extends CreateSessionLoginHandler;
private static class AutoConnectAnyDeviceLoginHandler extends CreateSessionLoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
if (Server.isUserRegistered(socketAction._sess.getUserLogin())) {
Log.logSysInfo("Session autoconnect - acquiring list of action threads...");
String[] sa = Server.getSessionList(socketAction._sess.getUserID());
Log.logSysInfo("Session autoconnect - list of action threads acquired.");
for (int i = 0; i < sa.length; i += 7) {
socketAction.abandonCommThreads();
Server.attachSocketToSession(sa[i + 1], socketAction._commSendThread.getSock());
return;
}
}
super.onLoginCorrect(socketAction);
}
}
private static class OnlyNewSessionLoginHandler extends CreateSessionLoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
socketAction.killOldSessionsForUser();
super.onLoginCorrect(socketAction);
}
}
}

Related

JUnit: Add two duplicated fixtures to some method

Hi I want to test duplication by adding same fixture more than twice. It could be the code below:
#Test(expected=DuplicationException.class)
public void saveFailedWithDuplicatedAccount(){
memberServiceImpl.save(member);
memberServiceImpl.save(member);
}
but I don't know how to deal with Mockito coding - like using when(), verify(). Since I am new to mockito, and I have got nothing found in the Google, so is there any example code to check duplicating addition?
You need to save state somewhere.
It may be some kind of internal storage or real database.
And you can extract logic for searching duplicates and mock that.
For example:
Test(expected = DuplicationException.class)
public void saveFailedWithDuplicatedAccount() {
DuplicateService duplicateServiceMock = Mockito.mock(DuplicateService.class);
memberServiceImpl.setDuplicateService(duplicateServiceMock);
memberServiceImpl.save(member);
Mockito.when(duplicateServiceMock.isDuplicate(member)).thenReturn(true);
memberServiceImpl.save(member);
}
public class DuplicateAccountService {
public boolean isDuplicateAccount(String login) {
return false; // Some logic for find duplicates
}
}

ASM Objectweb visitors without transformation

I want to use ASM to verify how often certain methods are called and what their arguments and result is. However, at runtime it ends with a java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "com/foo/bar/DefaultType".
For that reason I want to ensure that it is not an ASM (Objectweb) problem, so it tried to just pass the bytes without any modification with the following code:
#Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer)
throws IllegalClassFormatException {
byte[] result;
if(className.startsWith("com/foo/bar"))
{
ClassReader reader = new ClassReader(classfileBuffer);
try
{
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
reader.accept(writer, 0);
result = writer.toByteArray();
}
catch(Exception e)
{
result = null;
}
}
else
{
// do nothing
result = null;
}
return result;
}
But even after this modification I get the same Error. Any hints what I should change to get this code working?
Late answer to an old question.
One way these errors can occur is due to how the COMPUTE_FRAMES option of ClassWriter is implemented. In particular, the frame computation will sometimes need to figure out a common superclass for two given classes; to do this, it will load the classes it is interested in using Class.forName. If your codebase uses a non-trivial class loading setup, it may happen that a class gets loaded in an unpexected class loader this way (I can't recall the precise conditions, but I have had this happen to me). The solution is to override the getCommonSuperclass method of ClassWriter to perform the same computation in a safer way.

PowerMock: mock out private static final variable, a concrete example

what is the absolute minimal mocking that must be done to pass this test?
code:
class PrivateStaticFinal {
private static final Integer variable = 0;
public static Integer method() { return variable + 1; }
}
test:
#RunWith(PowerMockRunner.class)
#PrepareForTest(PrivateStaticFinal.class)
class PrivateStaticFinalTest {
#Test
public void testMethod() {
//TODO PrivateStaticFinal.variable = 100
assertEquals(PrivateStaticFinal.method(), 101);
}
}
related: Mock private static final variables in the testing class (no clear answer)
Disclaimer: After a lot of hunting around on various threads I have found an answer. It can be done, but the general concensus is that it is not very safe but seeing as how you are doing this ONLY IN UNIT TESTS, I think you accept those risks :)
The answer is not Mocking, since most Mocking does not allow you to hack into a final. The answer is a little more "hacky", where you are actually modifying the private field when Java is calling is core java.lang.reflect.Field and java.lang.reflect.Modifier classes (reflection). Looking at this answer I was able to piece together the rest of your test, without the need for mocking that solves your problem.
The problem with that answer is I was running into NoSuchFieldException when trying to modify the variable. The help for that lay in another post on how to access a field that was private and not public.
Reflection/Field Manipulation Explained:
Since Mocking cannot handle final, instead what we end up doing is hacking into the root of the field itself. When we use the Field manipulations (reflection), we are looking for the specific variable inside of a class/object. Once Java finds it we get the "modifiers" of it, which tell the variable what restrictions/rules it has like final, static, private, public, etc. We find the right variable, and then tell the code that it is accessible which allows us to change these modifiers. Once we have changed the "access" at the root to allow us to manipulate it, we are toggling off the "final" part of it. We then can change the value and set it to whatever we need.
To put it simply, we are modifying the variable to allow us to change its properties, removing the propety for final, and then changing the value since it is no longer final. For more info on this, check out the post where the idea came from.
So step by step we pass in the variable we want to manipulate and...
// Mark the field as public so we can toy with it
field.setAccessible(true);
// Get the Modifiers for the Fields
Field modifiersField = Field.class.getDeclaredField("modifiers");
// Allow us to change the modifiers
modifiersField.setAccessible(true);
// Remove final modifier from field by blanking out the bit that says "FINAL" in the Modifiers
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// Set new value
field.set(null, newValue);
Combining this all into a new SUPER ANSWER you get.
#RunWith(PowerMockRunner.class)
#PrepareForTest()
class PrivateStaticFinalTest {
#Test
public void testMethod(){
try {
setFinalStatic(PrivateStaticFinal.class.getDeclaredField("variable"), Integer.valueOf(100));
}
catch (SecurityException e) {fail();}
catch (NoSuchFieldException e) {fail();}
catch (Exception e) {fail();}
assertEquals(PrivateStaticFinal.method(), Integer.valueOf(101));
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
// remove final modifier from field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
}
Update
The above solution will work only for those constants which is initialized in static block.When declaring and initializing the constant at the same time, it can happen that the compiler inlines it, at which point any change to the original value is ignored.

Integrity of Law of Demeter preserved by using helper function (removed two dots)?

public House
{
WeatherStation station;
public float getTemp() {
//Law of Demeter has been violated here
return station.getThermometer().getTemperature();
}
}
public House
{
WeatherStation station;
public float getTemp() {
//Law of Demeter has been preserved?
Thermometer thermometer = station.getThermometer();
return getTempHelper(thermometer);
}
public float getTempHelper(Thermometer thermometer)
{
return thermometer.getTemperature();
}
}
In the code above you can see two different House class definitions. Both have getTemp() function, first of which violates Law of Demeter, but second one preservs it (according to Head First Design Patterns book).
The trouble is I don't quite get why second class preservs Law of Demeter, getTemp() function still has station.getThermometer() call, which (should?) violates Law of Demeter.
"use only one dot" - I found this on wikipedia, which could be applicable, but I still need more detailed explanation - "In particular, an object should avoid invoking methods of a member object returned by another method" (wiki).
So could anyone explain why the second code example does not violates the law? What truly distinguishes second method from first one?
I imagine there's a lot of discussion that can be had on the subject, but as I interpret it the purpose of the Law Of Demeter would be...
"You don't want to get the Thermometer from the Station. You want to get the Temperature from the Station."
Think of it from a real-life situation. You call up the weather station, you don't ask them, "What does the thermometer on the outside of your building say?" You ask them, "What is the current temperature?" The fact that they have a thermometer attached to the outside of their building isn't your concern. Maybe they replace the thermometer with an infrared laser pointed at a window. It doesn't matter to you. How they come by their information isn't your concern, you just want the information.
So, to that end, you'd end up with something like this:
public House
{
private WeatherStation _station;
public House(WeatherStation station)
{
_station = station;
}
public float GetTemperature()
{
return _station.GetTemperature();
}
}
public WeatherStation
{
private Thermometer _thermometer;
public WeatherStation(Thermometer thermometer)
{
_thermometer = thermometer;
}
public float GetTemperature()
{
return _thermometer.GetTemperature();
// This can be replaced with another implementation, or any other
// device which implements IThermometer, or a hard-coded test value, etc.
}
}
This leads to a few levels of nesting, which does appear to be a little distasteful. But keep in mind that each level, while currently called the exact same thing, means something slightly different. It's not really code duplication if the duplicated code has a different meaning. You could later break the chain with something like this:
public House
{
private WeatherStation _station;
public House(WeatherStation station)
{
_station = station;
}
public WeatherInfoDTO GetCurrentWeather()
{
var info = new WeatherInfoDTO();
info.Temperature = _station.GetTemperature();
//...
return info;
}
}
public WeatherInfoDTO
{
//...
}
public WeatherStation
{
private Thermometer _thermometer;
public WeatherStation(Thermometer thermometer)
{
_thermometer = thermometer;
}
public float GetTemperature()
{
return _thermometer.GetTemperature();
// This can be replaced with another implementation, or any other
// device which implements IThermometer, or a hard-coded test value, etc.
}
//...
}
By not hard-coding the top-level to the implementation of a Thermometer you allow for easy refactoring to support something like this.
It's only by the most strict definition of the law that the 2nd isn't in violation. In my opinion, its "legality is dubious" :), because you haven't properly abstracted away the caller's knowledge that the station uses a thermometer to obtain the temperature. Instead of the helper, I'd prefer to add a getTemperature() method to the station, encapsulating its use of a thermometer there.
In other words, both examples are aware of the station's implementation details, so removing the station's getThermometer() method will break both examples. To say the second is better kinda violates the spirit of the law, in my opinion.

Entity Framework Code First Deleting By ID Without Fetching (Generic Style)

Please tell me if this is a decent approach to deleting an Entity without fetching it given I have the ID.
I have a generic store with the following interface (I'll only show Delete):
public interface IStore : IReadOnlyStore
{
void Delete<TEntity>(TEntity entity) where TEntity : class, IEntity, new();
void SaveChanges();
}
And in the concrete Store class of that interface, here's my delete method:
public void Delete<TEntity>(TEntity entity) where TEntity : class, IEntity, new()
{
var obj = Ctx.Entry(entity);
if (obj.State == System.Data.EntityState.Detached)
{
Ctx.Set(typeof(TEntity)).Attach(obj.Entity);
}
Ctx.Set(typeof(TEntity)).Remove(obj.Entity);
}
I have tested both newing up an Entity:
Store.Delete(new Foo() { Id = request.Entity.Id });
as well as fetching an entity and then calling delete.
Through debugging, I have the desired affect on both scenarios.
I just want to make sure this is a good design and that there are no side effects to this approach.
For reference, Ctx is just the DbContext itself.
Thanks.
It's good design and doesn't have side effects :) (IMHO)
Two remarks:
I'm wondering if you could simplify your Delete method by:
public void Delete<TEntity>(TEntity entity)
where TEntity : class, IEntity, new()
{
Ctx.Entry(entity).State = EntityState.Deleted;
}
I would hope that setting the state to Deleted will attach automatically if the entity isn't already attached. But I am not sure if it works. (Let me know whether it works for attached and detached scenarios (if you should test this).)
If you have performance optimization in mind (avoiding to load the entities) don't forget that, if there are multiple entities to delete in the context, SaveChanges will still send one single DELETE statement per entity to the database. Bulk deletes with EF are quite terrible in performance and it's a terrain where going back to a SQL statements (DELETE ... WHERE ... IN ... many IDs....) sometimes makes sense (if performance matters).