答:
First, I completely agree with the answer from mattnz.  If you are worried about the cost of having to propose multiple designs before the client has something they like, you should definitely formally decide the terms of providing designs, in a contract, before design work begins.

Having said that, it only solves half your problem.  The main issue is that you are having a hard time designing something the client finds acceptable.  It really stood out to me where you describe the process of submitting new design ideas, and what you get back from those submissions.  I have been in that situation before.

I think maybe the problem is that you are dealing with someone other than the person or persons that OK the design.  I think you should see if you can have a meeting with the person that is actually making design approval decisions, so you can have a conversation with them about what they want.  Chances are, their requests, that come back as obscure "Should be more (insert vague term here)", will make a lot more sense to you if related in person.  It will also give you a chance to defend design decisions you made that the client doesn't like, but have been made for good reasons they might not know about.

Title: Who should provide the Requirement doc / SRS?

Body:
I am creating a Mobile application (CRM) for another software company. They told me they need these these stuff from here and there, within 15-30 minutes. But they never provided a detailed client requirement document in writing. I have been asking this for number of times, but still no. As soon as I started working I realized what they told by mouth is not even 10% of the work. They first asked me to come up with my own design which is similar to another app they mentioned. I did, 100% similar design to the app they mentioned. Then they said they don't like it so they gave me their design. I completed there design and submitted it. Now they again say they don't like their own design and asking me to do another design! Apart from that, they are asking for some "Activity Sliding Animations", "Windows Like UI" etc now. In order to do this, I need to remove the entire work I did and start from the scrach, because it can be done by Fragments and mine contains Activities. I even have no idea how the backend will be. Even after one month, we are still designing and changing the designing (Because you have to send at least 3-4 mails, contact at least 2 of their team via phone to get an answer. Very slow communication).

And will they pay for the trashed designs? I don't think so. So what about the other customers of mine which I said 'no' due to the lack of time I am going to have because of this project? I feel almost crazy.

They always say come up with your own idea, but that is very risky in this situation. If my idea is not accepted, waste of time and money.

I am so tired of this, I wasted lot of time designing two 100% different designing, and about to proceed to 3. Since I don't know how the software will be, I haven't done a cost estimation as well. So my question is, client is not supposed to give you any documented requirement? May be an SRS? (What I meant by SRS is, complete detailed document about functionality they need. Including these 'animation' stuff, because I have no super power to guess) The requirement doc they provided is useless, it only says "update", "delete", "edit". All my other clients did provide complete data, some even provided drafts of the design process, except this one. They should at lease ptovide me their requirements in details, in writing,  I need some advice here.


问:
What could be the Model Layer when consuming Web-Services and no Database in Django?
I'm using Django as an application framework and it only needs to consume web services (no need to have traditional Django Models and the related ORM).

In this case, since Django is a variant on the MVC architecture (MVT, to be precise) should I wrap the web service calls into a 'model' that my App uses or should I just call those web services directly from the Django View and remove the model layer?

答: I question the design choice of using a now-pretty-heavyweight web-framework and neglecting to use major parts of it. Look into using something like Flask instead.</p>

ContentLicense: CC BY-SA 3.0

OwnerDisplayName: Pete Tinkler


答:
you just run the syncdb and there are some extra tables which you never use from the views
also the views (at least on older djangos) has nothing to do with the models, just you can use models or not
so you just make an empty models.py for your new app
and btw it is called MTV and not MVC</p>

Title: What could be the Model Layer when consuming Web-Services and no Database in Django?

Body:
I'm using Django as an application framework and it only needs to consume web services (no need to have traditional Django Models and the related ORM).

In this case, since Django is a variant on the MVC architecture (MVT, to be precise) should I wrap the web service calls into a 'model' that my App uses or should I just call those web services directly from the Django View and remove the model layer?

OwnerDisplayName: tiborka


问:
Avoid too complex method - Cyclomatic Complexity
Not sure how to go about this method to reduce Cyclomatic Complexity. Sonar reports 13 whereas 10 is expected. I am sure nothing harm in leaving this method as it is, however, just challenging me how to go about obeying Sonar's rule. Any thoughts would be greatly appreciated.

```<code> public static long parseTimeValue(String sValue) {

    if (sValue == null) {
        return 0;
    }

    try {
        long millis;
        if (sValue.endsWith("S")) {
            millis = new ExtractSecond(sValue).invoke();
        } else if (sValue.endsWith("ms")) {
            millis = new ExtractMillisecond(sValue).invoke();
        } else if (sValue.endsWith("s")) {
            millis = new ExtractInSecond(sValue).invoke();
        } else if (sValue.endsWith("m")) {
            millis = new ExtractInMinute(sValue).invoke();
        } else if (sValue.endsWith("H") || sValue.endsWith("h")) {
            millis = new ExtractHour(sValue).invoke();
        } else if (sValue.endsWith("d")) {
            millis = new ExtractDay(sValue).invoke();
        } else if (sValue.endsWith("w")) {
            millis = new ExtractWeek(sValue).invoke();
        } else {
            millis = Long.parseLong(sValue);
        }

        return millis;

    } catch (NumberFormatException e) {
        LOGGER.warn("Number format exception", e);
    }

    return 0;
}
</code>```

All ExtractXXX methods are defined as static inner classes. For example, like one below -

```<code>    private static class ExtractHour {
      private String sValue;

      public ExtractHour(String sValue) {
         this.sValue = sValue;
      }

      public long invoke() {
         long millis;
         millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 60 * 60 * 1000);
         return millis;
     }
 }
</code>```

UPDATE 1

I am going to settle down with a mix of suggestions here to satisfy Sonar guy. Definitely room for improvements and simplification.

Guava Function is just a unwanted ceremony here. Wanted to update the question about current status. Nothing is final here. Pour your thoughts please..

```<code>public class DurationParse {

private static final Logger LOGGER = LoggerFactory.getLogger(DurationParse.class);
private static final Map<String, Function<String, Long>> MULTIPLIERS;
private static final Pattern STRING_REGEX = Pattern.compile("^(\\d+)\\s*(\\w+)");

static {

    MULTIPLIERS = new HashMap<>(7);

    MULTIPLIERS.put("S", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractSecond(input).invoke();
        }
    });

    MULTIPLIERS.put("s", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractInSecond(input).invoke();
        }
    });

    MULTIPLIERS.put("ms", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractMillisecond(input).invoke();
        }
    });

    MULTIPLIERS.put("m", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractInMinute(input).invoke();
        }
    });

    MULTIPLIERS.put("H", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractHour(input).invoke();
        }
    });

    MULTIPLIERS.put("d", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractDay(input).invoke();
        }
    });

    MULTIPLIERS.put("w", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractWeek(input).invoke();
        }
    });

}

public static long parseTimeValue(String sValue) {

    if (isNullOrEmpty(sValue)) {
        return 0;
    }

    Matcher matcher = STRING_REGEX.matcher(sValue.trim());

    if (!matcher.matches()) {
        LOGGER.warn(String.format("%s is invalid duration, assuming 0ms", sValue));
        return 0;
    }

    if (MULTIPLIERS.get(matcher.group(2)) == null) {
        LOGGER.warn(String.format("%s is invalid configuration, assuming 0ms", sValue));
        return 0;
    }

    return MULTIPLIERS.get(matcher.group(2)).apply(matcher.group(1));
}

private static class ExtractSecond {
    private String sValue;

    public ExtractSecond(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = Long.parseLong(sValue);
        return millis;
    }
}

private static class ExtractMillisecond {
    private String sValue;

    public ExtractMillisecond(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue));
        return millis;
    }
}

private static class ExtractInSecond {
    private String sValue;

    public ExtractInSecond(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 1000);
        return millis;
    }
}

private static class ExtractInMinute {
    private String sValue;

    public ExtractInMinute(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 60 * 1000);
        return millis;
    }
}

private static class ExtractHour {
    private String sValue;

    public ExtractHour(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 60 * 60 * 1000);
        return millis;
    }
}

private static class ExtractDay {
    private String sValue;

    public ExtractDay(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 24 * 60 * 60 * 1000);
        return millis;
    }
}

private static class ExtractWeek {
    private String sValue;

    public ExtractWeek(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 7 * 24 * 60 * 60 * 1000);
        return millis;
    }
}
</code>```

}

UPDATE 2

Though I added my update, it is only that much worth the time. I am going to move on since Sonar now does not complains. Don't worry much and I am accepting the mattnz answer as it is the way to go and don't want to set a bad example for those who bumps on to this question. Bottom line -- Don't over engineer for the sake of Sonar (or Half Baked Project Manager) complains about CC. Just do what's worth a penny for the project. Thanks to all.

答:
If you really want to refactor it, you could do something like this:

```<code>// All of your Extract... classes will have to implement this interface!
public Interface TimeExtractor
{
    public long invoke();
}

private static class ExtractHour implements TimeExtractor
{
  private String sValue;

  /*Not sure what this was for - might not be necessary now
  public ExtractHour(String sValue)
  {
     this.sValue = sValue;
  }*/

  public long invoke(String s)
  {
     this.sValue = s;
     long millis;
     millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 60 * 60 * 1000);
     return millis;
 }
}

private static HashMap<String, TimeExtractor> extractorMap= new HashMap<String, TimeExtractor>();

private void someInitMethod()
{
   ExtractHour eh = new ExtractorHour;
   extractorMap.add("H",eh);
   /*repeat for all extractors */
}

public static long parseTimeValue(String sValue)
{
    if (sValue == null)
    {
        return 0;
    }
    String key = extractKeyFromSValue(sValue);
    long millis;
    TimeExtractor extractor = extractorMap.get(key);
    if (extractor!=null)
    {
      try
      {
         millis= extractor.invoke(sValue);
      }
        catch (NumberFormatException e)
      {
          LOGGER.warn("Number format exception", e);
      }
    }
    else
       LOGGER.error("NO EXTRACTOR FOUND FOR "+key+", with sValue: "+sValue);

    return millis;
}
</code>```

The idea is you have a map of keys (what your using in "endsWith" all the time) that map to specific objects that do the processing you want.

It's a bit rough here but I hope it's clear enough. I didn't fill in the details of extractKeyFromSValue() because I just don't know enough of what these strings are to do it properly. It looks like it's the last 1 or 2 non-numeric characters (a regex could probably extract it easily enough, maybe .*([a-zA-Z]{1,2})$ would work), but I'm not 100% sure...

Original answer:

You could change

```<code>else if (sValue.endsWith("H") || sValue.endsWith("h")) {
</code>```

to

```<code>else if (sValue.toUpper().endsWith("H")) {
</code>```

That might save you a little bit, but honestly, I wouldn't worry about it too much. I agree with you that I don't think there's much harm in leaving the method as it is. Instead of trying to "obey Sonar's rules" try to "stay close to Sonar's guidelines, as much as is reasonably possible".

You can drive yourself mad trying to follow every single rule that these analysis tools will have in them, but you also have to decide if the rules make sense for your project, and for specific cases where the time spent refactoring just might not be worth it.

Body:
If you really want to refactor it, you could do something like this:

// All of your Extract... classes will have to implement this interface!
public Interface TimeExtractor
{
    public long invoke();
}

private static class ExtractHour implements TimeExtractor
{
  private String sValue;

  /*Not sure what this was for - might not be necessary now
  public ExtractHour(String sValue)
  {
     this.sValue = sValue;
  }*/

  public long invoke(String s)
  {
     this.sValue = s;
     long millis;
     millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 60 * 60 * 1000);
     return millis;
 }
}

private static HashMap<String, TimeExtractor> extractorMap= new HashMap<String, TimeExtractor>();

private void someInitMethod()
{
   ExtractHour eh = new ExtractorHour;
   extractorMap.add("H",eh);
   /*repeat for all extractors */
}

public static long parseTimeValue(String sValue)
{
    if (sValue == null)
    {
        return 0;
    }
    String key = extractKeyFromSValue(sValue);
    long millis;
    TimeExtractor extractor = extractorMap.get(key);
    if (extractor!=null)
    {
      try
      {
         millis= extractor.invoke(sValue);
      }
        catch (NumberFormatException e)
      {
          LOGGER.warn("Number format exception", e);
      }
    }
    else
       LOGGER.error("NO EXTRACTOR FOUND FOR "+key+", with sValue: "+sValue);

    return millis;
}

The idea is you have a map of keys (what your using in "endsWith" all the time) that map to specific objects that do the processing you want.

It's a bit rough here but I hope it's clear enough. I didn't fill in the details of extractKeyFromSValue() because I just don't know enough of what these strings are to do it properly. It looks like it's the last 1 or 2 non-numeric characters (a regex could probably extract it easily enough, maybe .*([a-zA-Z]{1,2})$ would work), but I'm not 100% sure...

Original answer:

You could change

else if (sValue.endsWith("H") || sValue.endsWith("h")) {

to

else if (sValue.toUpper().endsWith("H")) {

That might save you a little bit, but honestly, I wouldn't worry about it too much. I agree with you that I don't think there's much harm in leaving the method as it is. Instead of trying to "obey Sonar's rules" try to "stay close to Sonar's guidelines, as much as is reasonably possible".

You can drive yourself mad trying to follow every single rule that these analysis tools will have in them, but you also have to decide if the rules make sense for your project, and for specific cases where the time spent refactoring just might not be worth it.


答:
Thanks to @JimmyHoffa, @MichaelT, and @GlenH7 for their help!

Python

First things first, you should really only accept known prefixes, that is either 'H' or 'h'. If you have to accept both, you should perform some operation to make it consistent to save room in your map.

In python you could create a dictionary.

```<code>EXTRACTION_MAP = {
    'S': ExtractSecond,
    'ms': ExtractMillisecond,
    'm': ExtractMinute,
    'H': ExtractHour,
    'd': ExtractDay,
    'w': ExtractWeek
}
</code>```

Then we want the method to use this:

```<code>def parseTimeValue(sValue)
    ending = ''.join([i for i in sValue if not i.isdigit()])
    return EXTRACTION_MAP[ending](sValue).invoke()
</code>```

Should have a better cyclomatic complexity.

Java

We only need 1 (one) of each multiplier. Lets put them in a map as some other answers have suggest.

```<code>Map<String, Float> multipliers = new HashMap<String, Float>();
    map.put("S", 60 * 60);
    map.put("ms", 60 * 60 * 1000);
    map.put("m", 60);
    map.put("H", 1);
    map.put("d", 1.0 / 24);
    map.put("w", 1.0 / (24 * 7));
</code>```

Then we can just use the map to grab the right converter

```<code>Pattern foo = Pattern.compile(".*(\\d+)\\s*(\\w+)");
Matcher bar = foo.matcher(sValue);
if(bar.matches()) {
    return (long) (Double.parseDouble(bar.group(1)) * multipliers.get(bar.group(2);
}
</code>```

Title: Avoid too complex method - Cyclomatic Complexity

Body:
Not sure how to go about this method to reduce Cyclomatic Complexity. Sonar reports 13 whereas 10 is expected. I am sure nothing harm in leaving this method as it is, however, just challenging me how to go about obeying Sonar's rule. Any thoughts would be greatly appreciated.

```<code> public static long parseTimeValue(String sValue) {

    if (sValue == null) {
        return 0;
    }

    try {
        long millis;
        if (sValue.endsWith("S")) {
            millis = new ExtractSecond(sValue).invoke();
        } else if (sValue.endsWith("ms")) {
            millis = new ExtractMillisecond(sValue).invoke();
        } else if (sValue.endsWith("s")) {
            millis = new ExtractInSecond(sValue).invoke();
        } else if (sValue.endsWith("m")) {
            millis = new ExtractInMinute(sValue).invoke();
        } else if (sValue.endsWith("H") || sValue.endsWith("h")) {
            millis = new ExtractHour(sValue).invoke();
        } else if (sValue.endsWith("d")) {
            millis = new ExtractDay(sValue).invoke();
        } else if (sValue.endsWith("w")) {
            millis = new ExtractWeek(sValue).invoke();
        } else {
            millis = Long.parseLong(sValue);
        }

        return millis;

    } catch (NumberFormatException e) {
        LOGGER.warn("Number format exception", e);
    }

    return 0;
}
</code>```

All ExtractXXX methods are defined as static inner classes. For example, like one below -

```<code>    private static class ExtractHour {
      private String sValue;

      public ExtractHour(String sValue) {
         this.sValue = sValue;
      }

      public long invoke() {
         long millis;
         millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 60 * 60 * 1000);
         return millis;
     }
 }
</code>```

UPDATE 1

I am going to settle down with a mix of suggestions here to satisfy Sonar guy. Definitely room for improvements and simplification.

Guava Function is just a unwanted ceremony here. Wanted to update the question about current status. Nothing is final here. Pour your thoughts please..

```<code>public class DurationParse {

private static final Logger LOGGER = LoggerFactory.getLogger(DurationParse.class);
private static final Map<String, Function<String, Long>> MULTIPLIERS;
private static final Pattern STRING_REGEX = Pattern.compile("^(\\d+)\\s*(\\w+)");

static {

    MULTIPLIERS = new HashMap<>(7);

    MULTIPLIERS.put("S", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractSecond(input).invoke();
        }
    });

    MULTIPLIERS.put("s", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractInSecond(input).invoke();
        }
    });

    MULTIPLIERS.put("ms", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractMillisecond(input).invoke();
        }
    });

    MULTIPLIERS.put("m", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractInMinute(input).invoke();
        }
    });

    MULTIPLIERS.put("H", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractHour(input).invoke();
        }
    });

    MULTIPLIERS.put("d", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractDay(input).invoke();
        }
    });

    MULTIPLIERS.put("w", new Function<String, Long>() {
        @Nullable
        @Override
        public Long apply(@Nullable String input) {
            return new ExtractWeek(input).invoke();
        }
    });

}

public static long parseTimeValue(String sValue) {

    if (isNullOrEmpty(sValue)) {
        return 0;
    }

    Matcher matcher = STRING_REGEX.matcher(sValue.trim());

    if (!matcher.matches()) {
        LOGGER.warn(String.format("%s is invalid duration, assuming 0ms", sValue));
        return 0;
    }

    if (MULTIPLIERS.get(matcher.group(2)) == null) {
        LOGGER.warn(String.format("%s is invalid configuration, assuming 0ms", sValue));
        return 0;
    }

    return MULTIPLIERS.get(matcher.group(2)).apply(matcher.group(1));
}

private static class ExtractSecond {
    private String sValue;

    public ExtractSecond(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = Long.parseLong(sValue);
        return millis;
    }
}

private static class ExtractMillisecond {
    private String sValue;

    public ExtractMillisecond(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue));
        return millis;
    }
}

private static class ExtractInSecond {
    private String sValue;

    public ExtractInSecond(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 1000);
        return millis;
    }
}

private static class ExtractInMinute {
    private String sValue;

    public ExtractInMinute(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 60 * 1000);
        return millis;
    }
}

private static class ExtractHour {
    private String sValue;

    public ExtractHour(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 60 * 60 * 1000);
        return millis;
    }
}

private static class ExtractDay {
    private String sValue;

    public ExtractDay(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 24 * 60 * 60 * 1000);
        return millis;
    }
}

private static class ExtractWeek {
    private String sValue;

    public ExtractWeek(String sValue) {
        this.sValue = sValue;
    }

    public long invoke() {
        long millis;
        millis = (long) (Double.parseDouble(sValue) * 7 * 24 * 60 * 60 * 1000);
        return millis;
    }
}
</code>```

}

UPDATE 2

Though I added my update, it is only that much worth the time. I am going to move on since Sonar now does not complains. Don't worry much and I am accepting the mattnz answer as it is the way to go and don't want to set a bad example for those who bumps on to this question. Bottom line -- Don't over engineer for the sake of Sonar (or Half Baked Project Manager) complains about CC. Just do what's worth a penny for the project. Thanks to all.

Body:
Thanks to @JimmyHoffa, @MichaelT, and @GlenH7 for their help!

Python

First things first, you should really only accept known prefixes, that is either 'H' or 'h'. If you have to accept both, you should perform some operation to make it consistent to save room in your map.

In python you could create a dictionary.

EXTRACTION_MAP = {
    'S': ExtractSecond,
    'ms': ExtractMillisecond,
    'm': ExtractMinute,
    'H': ExtractHour,
    'd': ExtractDay,
    'w': ExtractWeek
}

Then we want the method to use this:

def parseTimeValue(sValue)
    ending = ''.join([i for i in sValue if not i.isdigit()])
    return EXTRACTION_MAP[ending](sValue).invoke()

Should have a better cyclomatic complexity.

Java

We only need 1 (one) of each multiplier. Lets put them in a map as some other answers have suggest.

Map<String, Float> multipliers = new HashMap<String, Float>();
    map.put("S", 60 * 60);
    map.put("ms", 60 * 60 * 1000);
    map.put("m", 60);
    map.put("H", 1);
    map.put("d", 1.0 / 24);
    map.put("w", 1.0 / (24 * 7));

Then we can just use the map to grab the right converter

Pattern foo = Pattern.compile(".*(\\d+)\\s*(\\w+)");
Matcher bar = foo.matcher(sValue);
if(bar.matches()) {
    return (long) (Double.parseDouble(bar.group(1)) * multipliers.get(bar.group(2);
}


答:
Software Engineering Answer:

This is just one of the many cases where simply counting beans that are simple to count will make you do the wrong thing. Its not a complex function, don't change it. Cyclomatic Complexity is merely a guide to complexity, and you are using it poorly if you change this function based on it. Its simple, its readable, its maintainable (for now), if it gets bigger in the future the CC will skyrocket exponentially and it will get the attention it needs when it needs needs it, not before.

Minion working for a Large Multinational Corporation Answer:

Organizations are full of overpaid, unproductive teams of bean counters. Keeping the bean counters happy is easier, and certainly wiser, than doing the right thing. You need to change the routine to get he CC down to 10, but be honest about why you are doing it - to keep the bean counters off your back. As suggested in comments - "monadic parsers" might help


问:
Open Source but not Free Software (or vice versa)
The definition of "Free Software" from the Free Software Foundation:

“Free software” is a matter of
  liberty, not price. To understand the
  concept, you should think of “free” as
  in “free speech,” not as in “free
  beer.”

Free software is a matter of the
  users' freedom to run, copy,
  distribute, study, change and improve
  the software. More precisely, it means
  that the program's users have the four
  essential freedoms:

The freedom to run the program, for
  any purpose (freedom 0).

The freedom
  to study how the program works, and
  change it to make it do what you wish
  (freedom 1). Access to the source
  code is a precondition for this.

The
  freedom to redistribute copies so you
  can help your neighbor (freedom 2).

The freedom to distribute copies of
  your modified versions to others
  (freedom 3). By doing this you can
  give the whole community a chance to
  benefit from your changes. Access to
  the source code is a precondition for
  this.

A program is free software if users
  have all of these freedoms. Thus, you
  should be free to redistribute copies,
  either with or without modifications,
  either gratis or charging a fee for
  distribution, to anyone anywhere.
  Being free to do these things means
  (among other things) that you do not
  have to ask or pay for permission to
  do so.

The definition of "Open Source Software" from the Open Source Initiative:

Open source doesn't just mean access
  to the source code. The distribution
  terms of open-source software must
  comply with the following criteria:

Free Redistribution The license shall not restrict any party from
  selling or giving away the software as
  a component of an aggregate software
  distribution containing programs from
  several different sources. The license
  shall not require a royalty or other
  fee for such sale.

Source Code The program must include source code, and must allow
  distribution in source code as well as
  compiled form. Where some form of a
  product is not distributed with source
  code, there must be a well-publicized
  means of obtaining the source code for
  no more than a reasonable reproduction
  cost preferably, downloading via the
  Internet without charge. The source
  code must be the preferred form in
  which a programmer would modify the
  program. Deliberately obfuscated
  source code is not allowed.
  Intermediate forms such as the output
  of a preprocessor or translator are
  not allowed.

Derived Works The license must allow modifications and derived works,
  and must allow them to be distributed
  under the same terms as the license of
  the original software.

Integrity of The Author's Source Code The license may restrict
  source-code from being distributed in
  modified form only if the license
  allows the distribution of "patch
  files" with the source code for the
  purpose of modifying the program at
  build time. The license must
  explicitly permit distribution of
  software built from modified source
  code. The license may require derived
  works to carry a different name or
  version number from the original
  software.

No Discrimination Against Persons or Groups The license must not
  discriminate against any person or
  group of persons.

No Discrimination Against Fields of Endeavor The license must not restrict
  anyone from making use of the program
  in a specific field of endeavor. For
  example, it may not restrict the
  program from being used in a business,
  or from being used for genetic
  research.

Distribution of License The rights attached to the program must apply to
  all to whom the program is
  redistributed without the need for
  execution of an additional license by
  those parties.

License Must Not Be Specific to a Product The rights attached to the
  program must not depend on the
  program's being part of a particular
  software distribution. If the program
  is extracted from that distribution
  and used or distributed within the
  terms of the program's license, all
  parties to whom the program is
  redistributed should have the same
  rights as those that are granted in
  conjunction with the original software
  distribution.

License Must Not Restrict Other Software The license must not place
  restrictions on other software that is
  distributed along with the licensed
  software. For example, the license
  must not insist that all other
  programs distributed on the same
  medium must be open-source software.

License Must Be Technology-Neutral No provision of the license may be
  predicated on any individual
  technology or style of interface.

These definitions, although they derive from very different ideologies, are broadly compatible, and most Free Software is also Open Source Software and vice versa. I believe, however, that it is possible for this not to be the case: It is possible for software to be Open Source without being Free, or to be Free without being Open Source.

Questions

Is my belief correct? Is it possible for software to fall into one camp and not the other?

Does any such software actually exist? Please give examples.

Clarification

I've already accepted an answer now, but I seem to have confused a lot of people, so perhaps a clarification is in order. I was not asking about the difference between copyleft (or "viral", though I don't like that term) and non-copyleft ("permissive") licenses. Nor was I asking about your personal idiosyncratic definitions of "Free" and "Open". I was asking about "Free Software as defined by the FSF" and "Open Source Software as defined by the OSI". Are the two always the same? Is it possible to be one without being the other?

And the answer, it seems, is that it's impossible to be Free without being Open, but possible to be Open without being Free. Thank you everyone who actually answered the question.

答: According to Wikipedia, any software licensed under the NASA Open Source Agreement is open source, but not free, so that would be one example.</p>

ContentLicense: CC BY-SA 2.5


问:
How Challenging is it to Mix Pure JS with CoffeeScript on a Team?
I keep running into Senior JS positions where they want CoffeeScript. The reason I don't use CoffeeScript is that my first impression of it was that it puts limitations on JS OOP features that I find valuable. I've seen claims that the two can inter-mix freely but that sounds dubious to me. Should I even bother applying to these positions if CoffeeScript-only is a dealbreaker for me?</p>

答:
Above sarcasm not withstanding, my answer to your question would be "yes."

Assuming that the position is otherwise something that would be a good fit, it would be a shame to miss out on an opportunity solely due to a language flavor that may or may not be in widespread use in a few years. In addition, if your OOP concerns are genuine, it would be well worth bringing this up in an interview.


问:
Using a function's return value as an if condition, good practice?
Do you think it is a good practice to use function return values as if conditions? I'm coding in PHP atm but it holds for many other languages.

```<code>if(isTheConditionMet($maybeSomeParams))
{
}
</code>```

or

```<code>$res = isTheConditionMet($maybeSomeParams);
if($res)
{
}
</code>```

I can't think of a situation where the first one creates a problem, can it?

EDIT: Assume return value is not going to be used after condition is evaluated.

答:
In the code you posted, there's no reason to store the function result in a variable before using it. (Unless perhaps the name of the variable is sufficiently meaningful that it makes the code clearer to the reader.)

On the other hand, if you need to refer to the value more than once, you should probably store it in a variable rather than calling the function multiple times, which could be inefficient and/or wrong:

```<code>$res = isTheConditionMet($maybeSomeParams);
if ($res)
{
    echo "res = $res\n";
    // do stuff
}
</code>```

Body:
In the code you posted, there's no reason to store the function result in a variable before using it. (Unless perhaps the name of the variable is sufficiently meaningful that it makes the code clearer to the reader.)

On the other hand, if you need to refer to the value more than once, you should probably store it in a variable rather than calling the function multiple times, which could be inefficient and/or wrong:

$res = isTheConditionMet($maybeSomeParams);
if ($res)
{
    echo "res = $res\n";
    // do stuff
}


问:
What is the need of Odata when I have JSON?
I am trying to understand the point of Odata and when it would make sense. Right now how I work is I use ASP.NET and MVC/WebApi controller to serialize/deserialize objects into JSON and have javascript do something with it.

From what I can tell the benefit of OData is being able to query directly from the URL ... But since I am writing the client and server code there is no need for that.

Would anyone ever parse the results of a ODaya query in javascript??

Maybe OData is more about providing a generic endpoint for ALL clients to get detailed information from a query that JSON does not provide ? So if I was a provider of data then I suppose that is what odata is for ?

Help me understand the purpose and use of REST/JSON/ODATA.

答: For the "why" question, there is a really good definition in the book RESTful Web APIs - essentially OData implements a collection pattern, where a collection is a resource that provides a list of resources through links.</p>

ContentLicense: CC BY-SA 4.0


答:
Assuming that the code is working fine, and you do not need to debug it.

Since, you are not going to use the variable $res, you shouldn't have it there either. In code block 1 there is one comparison operation on the return value of isTheConditionMet.

In code block 2 the return value is being assigned to $res and then being compared in if. Why have an extra assignment operation.

Title: Using a function's return value as an if condition, good practice?

Body:
Do you think it is a good practice to use function return values as if conditions? I'm coding in PHP atm but it holds for many other languages.

```<code>if(isTheConditionMet($maybeSomeParams))
{
}
</code>```

or

```<code>$res = isTheConditionMet($maybeSomeParams);
if($res)
{
}
</code>```

I can't think of a situation where the first one creates a problem, can it?

EDIT: Assume return value is not going to be used after condition is evaluated.


答:
The only case where the former can cause a problem, or be annoying, is when you use a debugger that doesn't or can't evaluate the function while you're debugging. Until recently, this was the case for .NET functions/visual studio.

I can't say for certain, but I would suspect that a decent optimizer would optimize the variable out to conserve memory.


问:
How strict should you be about indentation/white space?
Our development process is as follows

code the task -> someone else QAs code and documentation -> task is merged into trunk.

Recently a colleague is refusing to pass the code QA due to issues with indentation and whitespace.

Here are examples of these issues (syntax is SAS):

Additional whitespace:

```<code>        %if &syserr gt 0 %then %goto err; /*last line of code*/

/* Footer area*/
</code>```

Extra line of white space, and not indented inside proc sort:

```<code> /* End Of header * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    proc sort data = %dataset ;
    by id;
    run;
    %if &syserr gt 0 %then %goto err;

    proc sort data = &second_dataset.;
    by id;
    run;
    %if &syserr gt 0 %then %goto err;
</code>```

Extra white space between steps:

```<code>        /*join all details on for each record*/
        proc sort data = &data out = data_srt ;
              by &conditions;
        run;
        %if &syserr gt 0 %then %goto err;

        proc sort data = &data2.;
              by &conditions.;
        run;
        %if &syserr gt 0 %then %goto err;

        /*cartesian join*/
        data new_data;
              join data
                          &data2.  ;
              by &conditions;

        run;
</code>```

The question is, being a good programmer, is looking over your code and correcting all this kind of thing the right thing to do, or is this just ridiculous?

There is an additional complication, that because we don't have continuous integration or automated testing, it's not possible for the QAer to quickly fix up these issues and commit the code, for risk of accidentally deleting semicolon or something. (To be fair, the risk applies to the initial developer making these changes, so either way if this mistake occurs, it just needs to be fixed and move on).

答:
This is absolutely the correct thing to do. One of the biggest parts of code quality is its readability. If you haven't indented your code properly and you have random whitespace everywhere it reduces the readability of the code.

Generally, your development team should all follow the same code quality standards when it comes to indentation and whitespace. If other modules in your code base don't put extra whitespace between steps then this one shouldn't either (unless of course, it improves readability).

I'm not a SAS programmer, but if I'm reviewing code and the indenting is all out of whack and it doesn't look tidy I certainly comment on it for follow up and, if really bad, fail the review.


答:
As Uncle Bob says in his book, formatting (even whitespace) is incredibly important. Software tends to be read much more often than written, so it behooves us to make it clean and easy to read. It's a method of communication.

Ideally, when working in a team, you'll determine a standard and everybody follows it. Ideally, instead of nitpicking the standard in individual code reviews, set up a tool that will do the job for you. (Not sure what tool would work for your case; something like checkstyle for Java or StyleCop for C#).

So I'd chat with your colleague and see if you can't come up with some guidelines about whitespace. Taking a couple minutes to clean up your code is worth it if it makes things consistent down the line.

Title: How strict should you be about indentation/white space?

Body:
Our development process is as follows

code the task -> someone else QAs code and documentation -> task is merged into trunk.

Recently a colleague is refusing to pass the code QA due to issues with indentation and whitespace.

Here are examples of these issues (syntax is SAS):

Additional whitespace:

```<code>        %if &syserr gt 0 %then %goto err; /*last line of code*/

/* Footer area*/
</code>```

Extra line of white space, and not indented inside proc sort:

```<code> /* End Of header * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    proc sort data = %dataset ;
    by id;
    run;
    %if &syserr gt 0 %then %goto err;

    proc sort data = &second_dataset.;
    by id;
    run;
    %if &syserr gt 0 %then %goto err;
</code>```

Extra white space between steps:

```<code>        /*join all details on for each record*/
        proc sort data = &data out = data_srt ;
              by &conditions;
        run;
        %if &syserr gt 0 %then %goto err;

        proc sort data = &data2.;
              by &conditions.;
        run;
        %if &syserr gt 0 %then %goto err;

        /*cartesian join*/
        data new_data;
              join data
                          &data2.  ;
              by &conditions;

        run;
</code>```

The question is, being a good programmer, is looking over your code and correcting all this kind of thing the right thing to do, or is this just ridiculous?

There is an additional complication, that because we don't have continuous integration or automated testing, it's not possible for the QAer to quickly fix up these issues and commit the code, for risk of accidentally deleting semicolon or something. (To be fair, the risk applies to the initial developer making these changes, so either way if this mistake occurs, it just needs to be fixed and move on).


答:
Yes, that's the right response. The indentation style should be consistent for all code.

A big part of the value of consistent indentation is that it's consistent. That way people learn to read it easily, which speeds up everyone.

My rule of thumb is that any indentation style the team wants is good, as long as it can be mechanically applied. Applying it mechanically means that you don't have to learn the details of the standard, or spend time twiddling whitespace.

Mechanical formatting also becomes another way that errors stand out. If you think you've enclosed code in a block the format tool will un-indent it and it'll be obvious that you messed up. This also makes refactoring easier - at the trivial level when you extract a block of code to a function, autoformat will remove the extra indentation.

Autoformat also means that if you really, really can't live with the standard everyone else uses you can format code the way you like it, then reformat it back before you check it in. Since you have a review step, you'd obviously do that before the review and if you didn't it would be picked up then.

GNU indent is one tool that can be made to autoformat almost anything. I did a quick search and there seem to be tools around to auto format SAS code but the SAS tools don't do that for you.


答:
How challenging technically is it to mix them? Or how challenging from a process and teamwork perspective?

I get the feeling you're asking about the former, but when it comes to jobs which advertise that they want CoffeeScript experience, it's more likely to be the latter that is relevant.

And I can tell you right now, if my workplace currently uses "language X", and we advertise for developers who know "language X", we might hire someone who knows "language Y" and is keen and willing to learn X. But we won't hire someone who knows "language Y" and wants to come in and use "language Y", suggesting that the code all our other developers write should be able to inter-mix with it.

Title: How Challenging is it to Mix Pure JS with CoffeeScript on a Team?

Body: I keep running into Senior JS positions where they want CoffeeScript. The reason I don't use CoffeeScript is that my first impression of it was that it puts limitations on JS OOP features that I find valuable. I've seen claims that the two can inter-mix freely but that sounds dubious to me. Should I even bother applying to these positions if CoffeeScript-only is a dealbreaker for me?</p>


问:
Is the Java package name convention flawed?
We're all familiar with the Java package name convention of turning the domain name around. I.e. www.evilcorp.com would, by convention, chose to have their java packages com.evilcorp.stuff.

Increasingly I'm getting fed up with this. As a commercial programmer, I encounter time and again that the software package name is completely irrelevant due to some rebrand, acquisition or similar.

In the opensource world there's less name changes so there it makes sense. However it seems to me the shelf life of many pieces of (commercial/internal) software are much longer than that of the organisation making them.

The problem is often made worse by software projects taking the marketing department's lead to use the name du jour they use refer to a certain project. A name that will, without fail, change 3 months down the line to make the emperor's new clothes feel fresh and new.

Because of this, I've mostly stopped using the reverse domain as package name. Granted, if this is done on a large scale, there's risk of name collisions, but surely this is mitigated by either using "unique" software names, avoiding generic words, or use the reverse domain for projects intended to be sold/released as libraries.

Other thoughts?

答:
The reverse domain name was used to avoid name collisions in case different organizations use the same class names in their libraries. It is a simple solution and off cource has some drawbacks (e.g. what about name collisions for classes in the same organization?).

You are not obligated to use it, it is a convention not a do or die rule. For example, some Java programmers don't respect the Java Code Conventions.

But consider the alternatives. How would you, for example, like two fully qualified class names for a LogFactory:

```<code>a50e8400_e29b_41d4_a716_446655440000.LogFactory
f47ac10b_58cc_4372_a567_0e02b2c3d479.Logfactory
</code>```

or

```<code>org.apache.commons.logging.LogFactory
com.evilcorp.logging.LogFactory
</code>```

So, in my thoughts, use whatever you like as long as it includes common sense and a consideration for the users of your library.

Body:
The reverse domain name was used to avoid name collisions in case different organizations use the same class names in their libraries. It is a simple solution and off cource has some drawbacks (e.g. what about name collisions for classes in the same organization?).

You are not obligated to use it, it is a convention not a do or die rule. For example, some Java programmers don't respect the Java Code Conventions.

But consider the alternatives. How would you, for example, like two fully qualified class names for a LogFactory:

a50e8400_e29b_41d4_a716_446655440000.LogFactory
f47ac10b_58cc_4372_a567_0e02b2c3d479.Logfactory

or

org.apache.commons.logging.LogFactory
com.evilcorp.logging.LogFactory

So, in my thoughts, use whatever you like as long as it includes common sense and a consideration for the users of your library.


答:
After an experience many years ago, reading some F-16C/D code where the indentation was broken, I have to say that getting the indentation correct is critically important.

It is so critically important that it should not be done by hand and it should not be fixed by hand.  This is what computers are for.

They make computer programs that can automatically reformat source code to match your company's preferred style.  Hook one of them up to your source code control system, so that the code is automagically brought into compliance whenever it is checked in.


问:
What's wrong with circular references?
I was involved in a programming discussion today where I made some statements that basically assumed axiomatically that circular references (between modules, classes, whatever) are generally bad.  Once I got through with my pitch, my coworker asked, "what's wrong with circular references?"

I've got strong feelings on this, but it's hard for me to verbalize concisely and concretely.  Any explanation that I may come up with tends to rely on other items that I too consider axioms ("can't use in isolation, so can't test", "unknown/undefined behavior as state mutates in the participating objects", etc.), but I'd love to hear a concise reason for why circular references are bad that don't take the kinds of leaps of faith that my own brain does, having spent many hours over the years untangling them to understand, fix, and extend various bits of code.

Edit: I am not asking about homogenous circular references, like those in a doubly-linked list or pointer-to-parent.  This question is really asking about "larger scope" circular references, like libA calling libB which calls back to libA.  Substitute 'module' for 'lib' if you like.  Thanks for all of the answers so far!

答:
While I agree with most of the comments here I would like to plead a special case for the "parent"/"child" circular reference.

A class often needs to know something about its parent or owning class, perhaps default behavior, the name of the file the data came from ,the sql statement that selected the column, or, the location of a log file etc.

You can do this without a circular reference by having a containing class so that what was previously the "parent" is now a sibling, but it is not always possible to re-factor existing code to do this.

The other alternative is to pass all the data a child might need in its constructor, which end up being just plain horrible.

Title: What's wrong with circular references?


答: If you can look at it the next day and it's obvious and easy to read, there's no need for the assignment. But it had a ton of args, or was accompanied by many other function calls in those if parens along with a bunch of operators, I'd drop it in a well-named var to explain what the crap you're actually intending to switch on.</p>


问:
Why do people confuse C-type strings and STL strings
The last week I saw at least three questions where people were confused about the differences between char * and std::string or made some related mistakes.

Don't get me wrong, I don't have a problem with this, I just don't get the exact reason for this. Maybe it was just a coincidence.

答: Because they're both commonly known as "strings" in a language that has no real string type.  It's very understandable that inexperienced coders would be confused by that...</p>


问:
Which one of these designs is preferred?
In the case of an application with a single simple responsibility (eg, a simple replacement for grep or wc), which of these designs is preferred and why? I find that they are all testable and they all do their job. Does any of them have any significant advantages over the other?

1: All methods in the main class:

```<code>public class App {
    public static void main(String[] args)
    {
        App app = new App();
        AppInput input = app.readInput();
        AppOutput output = app.processInputToOutput(input);
        app.writeOutput(output);
    }

    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}
</code>```

2: Basic methods in a separate class, main class only making calls to read and process input, and output result:

```<code>public class App {
    public static void main(String[] args)
    {
        AppWorker worker = new AppWorker();
        AppInput input = worker.readInput();
        AppOutput output = worker.processInputToOutput(input);
        worker.writeOutput(output);
    }
}

public class AppWorker {
    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}
</code>```

3: Have all the work in a separate worker class, with the main class only instantiating the worker and triggering it to do its work:

```<code>public class App {
    public static void main(String[] args)
    {
        AppWorker worker = new AppWorker();
        worker.doYourWork();
    }
}

public class AppWorker {
    public void doYourWork()
    {
        AppInput input = readInput();
        AppOutput output = processInputToOutput(input);
        writeOutput(output);
    }

    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }

}
</code>```

答:
Please notice that for the most part, these are nitpick details and refer to the general best practice of structuring code, however I'd be arrogant to assume to know how you should write your program.

That being said, lets look at #1:

Solution #1

```<code>// Name of class containing main should usually be called Main and
// Main in of itself is a single responsibility class, meaning it does nothing
// other than launch your program
public class App {
    public static void main(String[] args)
    {
        // Here, "App" should be a more significant name relevant to what it does.
        // Perhaps "Pipe" would be better suited?
        App app = new App();
        AppInput input = app.readInput();
        AppOutput output = app.processInputToOutput(input);
        app.writeOutput(output);
    }

    // These methods would obviously belong to Pipe and not to App/Main
    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}
</code>```

Solution #2

```<code>// Same discussion as above with name of class containing Main
public class App {
    public static void main(String[] args)
    {
        // Correcting minor error using "app" in the place of "worker"
        AppWorker worker = new AppWorker();
        AppInput input = worker.readInput();
        AppOutput output = worker.processInputToOutput(input);
        worker.writeOutput(output);
    }
}

// AppWorker seems to uphold the suggestions mentioned above, but the name is a problem.
// "Worker" makes me think of threads.  If it isn't a thread, you would probably be better
// off calling it with a name appropriate for its job (again, I propose Pipe as
// it takes input and writes output).
public class AppWorker {
    // "readInput" and "writeOutput" are redundant.  Better left as "read/write"
    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}
</code>```

Solution #3

```<code>// Same discussion as above with name of class containing Main
public class App {
    public static void main(String[] args)
    {
        // This is simply moving the job of Main to another class.
        // In more complicated programs, this may even be smart.  Controller classes
        // are usually used when Main begins to be cluttered, leaving the logic of
        // argument handling in Main and putting the rest in the controller class.
        // However in this case, "AppWorker" does nothing more than the work of App/Main
        // which makes AppWorker simply redundant.
        AppWorker worker = new AppWorker();
        worker.doYourWork();
    }
}

public class AppWorker {
    public void doYourWork()
    {
        // You mean to use this here I assume?
        // App app = new App();
        AppInput input = this.readInput();
        AppOutput output = this.processInputToOutput(input);
        this.writeOutput(output);
    }

    // If AppWorker is controller as it seems to be, the following methods need to be
    // protected or private as this class controls and is not controlled.  Only
    // public methods aside from "execute" method should be to set optional parameters.
    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}
</code>```

My Solution

If I may be so bold, applying the points above, I would write it as the following:

```<code>public class Main{
    public static void main(String[] args)
    {
        Pipe pipe = new Pipe();
        PipeInput input = pipe.read();
        PipeOutput output = pipe.processInputToOutput(input);
        pipe.write(output);
    }
}

public class Pipe {
    public PipeInput read() { .. }
    public PipeOutput processInputToOutput(PipeInput input) { .. }
    public void write(PipeOutput output) { .. }
}
</code>```

Notice that the logic hasn't been removed from Main, but it is still left simple.  If I saw that my Main were getting cluttered, I would consider creating a class to handle some of the more trivial details, but not to the point where I would create a class that does everything Main does.  Not even when I want to create a controller class do I port all the logic.  Controller can make some assumptions about the input, and Main can provide the necessary tests.

The work of App is now called Pipe.  Notice that it follows the single responsibility principle.  If I wanted to add more logic, I would be careful not to automatically add it to Pipe, since Pipe already does everything it should and nothing more.  And finally, note that the names of the methods previously called readInput and writeOutput are now simply read and write, since in the context of Pipe, it is clear what is intended by the parameters passed.

Again, these are nitpicky details.  I'm simply following the best practices that I've learned over the years.  I hope that you can also benefit from these tips!

Body:
Please notice that for the most part, these are nitpick details and refer to the general best practice of structuring code, however I'd be arrogant to assume to know how you should write your program.

That being said, lets look at #1:

Solution #1

// Name of class containing main should usually be called Main and
// Main in of itself is a single responsibility class, meaning it does nothing
// other than launch your program
public class App {
    public static void main(String[] args)
    {
        // Here, "App" should be a more significant name relevant to what it does.
        // Perhaps "Pipe" would be better suited?
        App app = new App();
        AppInput input = app.readInput();
        AppOutput output = app.processInputToOutput(input);
        app.writeOutput(output);
    }

    // These methods would obviously belong to Pipe and not to App/Main
    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}

Solution #2

// Same discussion as above with name of class containing Main
public class App {
    public static void main(String[] args)
    {
        // Correcting minor error using "app" in the place of "worker"
        AppWorker worker = new AppWorker();
        AppInput input = worker.readInput();
        AppOutput output = worker.processInputToOutput(input);
        worker.writeOutput(output);
    }
}

// AppWorker seems to uphold the suggestions mentioned above, but the name is a problem.
// "Worker" makes me think of threads.  If it isn't a thread, you would probably be better
// off calling it with a name appropriate for its job (again, I propose Pipe as
// it takes input and writes output).
public class AppWorker {
    // "readInput" and "writeOutput" are redundant.  Better left as "read/write"
    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}

Solution #3

// Same discussion as above with name of class containing Main
public class App {
    public static void main(String[] args)
    {
        // This is simply moving the job of Main to another class.
        // In more complicated programs, this may even be smart.  Controller classes
        // are usually used when Main begins to be cluttered, leaving the logic of
        // argument handling in Main and putting the rest in the controller class.
        // However in this case, "AppWorker" does nothing more than the work of App/Main
        // which makes AppWorker simply redundant.
        AppWorker worker = new AppWorker();
        worker.doYourWork();
    }
}

public class AppWorker {
    public void doYourWork()
    {
        // You mean to use this here I assume?
        // App app = new App();
        AppInput input = this.readInput();
        AppOutput output = this.processInputToOutput(input);
        this.writeOutput(output);
    }

    // If AppWorker is controller as it seems to be, the following methods need to be
    // protected or private as this class controls and is not controlled.  Only
    // public methods aside from "execute" method should be to set optional parameters.
    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}

My Solution

If I may be so bold, applying the points above, I would write it as the following:

public class Main{
    public static void main(String[] args)
    {
        Pipe pipe = new Pipe();
        PipeInput input = pipe.read();
        PipeOutput output = pipe.processInputToOutput(input);
        pipe.write(output);
    }
}

public class Pipe {
    public PipeInput read() { .. }
    public PipeOutput processInputToOutput(PipeInput input) { .. }
    public void write(PipeOutput output) { .. }
}

Notice that the logic hasn't been removed from Main, but it is still left simple.  If I saw that my Main were getting cluttered, I would consider creating a class to handle some of the more trivial details, but not to the point where I would create a class that does everything Main does.  Not even when I want to create a controller class do I port all the logic.  Controller can make some assumptions about the input, and Main can provide the necessary tests.

The work of App is now called Pipe.  Notice that it follows the single responsibility principle.  If I wanted to add more logic, I would be careful not to automatically add it to Pipe, since Pipe already does everything it should and nothing more.  And finally, note that the names of the methods previously called readInput and writeOutput are now simply read and write, since in the context of Pipe, it is clear what is intended by the parameters passed.

Again, these are nitpicky details.  I'm simply following the best practices that I've learned over the years.  I hope that you can also benefit from these tips!


问:
What to send when a client wants a sample of my code to test my qualities?
We've all faced this. You apply to a cool project and they ask you to send them a piece of your code. On the surface, this look OK and I am fine with it.

But what shall I send them? My cool utility? Snapshot of structure in complex project? Something else?

So far, I have tried to persuade them to have a desktop share via Skype and that I lead them through code and structure. But somehow clients do not like this approach.

So I'd like to hear your thoughts.

答:
Do you keep track of the stuff you've built for other clients?

If you are a freelancer (it seems like you are) you should keep links to past projects you've done for other clients. I know that as a client I would click on the other projects to see exactly what you're capable of. Client testimonials would go well with this too.

Of course you don't want to define yourself by just your past projects, so you could also keep links within your website to demo projects you've worked on too (normally your demos should highlight how 'deep' your knowledge level goes - as chances are, you haven't built that many complex projects for clients). Snapshots could work here too (if you don't have links to actual demo projects).

Lastly, for displaying code, you can just link to your GitHub account to your website. You don't want anyone having access to proprietary code you've written for another client, and GitHub (or even bitbucket) is a great place to display code you want displayed (remember though, seeing your code will depend on the client, as most won't care about that unless they are technical firms themselves).

PS. You should just note that in situations like these, you are marketing yourself (especially if you are a freelancer). It is important that you look for strategies to improve your brand (which is basically YOU).


答:
Since you return millis at the end of that awful ifelseifelse anyway, first thing that comes to mind is to return the value immediately from within if-blocks. This approach follows one that is listed in catalog of refactoring patterns as Replace Nested Conditional with Guard Clauses.

A method has conditional behavior that does not make clear what the normal path of execution is

Use Guard Clauses for all the special cases

It will help you get rid of else's, flatten the code and make Sonar happy:

```<code>    if (sValue.endsWith("S")) {
        return new ExtractSecond(sValue).invoke();
    } // no need in else after return, code flattened

    if (sValue.endsWith("ms")) {
        return new ExtractMillisecond(sValue).invoke();
    }

    // and so on...
    return Long.parseLong(sValue); // forget millis, these aren't needed anymore
</code>```

Another thing worth considering is dropping the try-catch block. This will also lower cyclomatic complexity, but main reason why I recommend it is that with this block, there is no way for caller code to distinguish legally parsed 0 from number format exception.

Unless you're 200% certain that returning 0 for parse errors is what caller code needs, you better propagate that exception up and let caller code decide how to deal with it. It is typically more convenient to decide at caller whether to abort execution or retry getting input, or fall back to some default value like 0 or -1 or whatever.

Your code snippet for an example ExtractHour makes me feel that ExtractXXX functionality is designed in a way far from optimal. I bet every of the remaining classes thoughtlessly repeats same parseDouble and substring, and multiplying stuff like 60 and 1000 over and over and over again.

This is because you missed the essence of what needs to be done depending on sValue - namely, it defines how much chars to cut from the end of the string and what would be the multiplier value. If you design your "core" object around these essential features, it would look like as follows:

```<code>private static class ParseHelper {
    // three things you need to know to parse:
    final String source;
    final int charsToCutAtEnd;
    final long multiplier;

    ParseHelper(String source, int charsToCutAtEnd, long multiplier) {
        this.source = source == null ? "0" : source; // let's handle null here
        this.charsToCutAtEnd = charsToCutAtEnd;
        this.multiplier = multiplier;
    }

    long invoke() {
        // NOTE consider Long.parseLong instead of Double.parseDouble here
        return (long) (Double.parseDouble(cutAtEnd()) * multiplier);
    }

    private String cutAtEnd() {
        if (charsToCutAtEnd == 0) {
            return source;
        }
        // write code that cuts 'charsToCutAtEnd' from the end of the 'source'
        throw new UnsupportedOperationException();
    }
}
</code>```

After that, you'd need a code that configures above objects per particular condition if it is met, or somehow "bypasses" otherwise. This could be done about as follows:

```<code>private ParseHelper setupIfInSecond(ParseHelper original) {
    final String sValue = original.source;
    return sValue.endsWith("s") && !sValue.endsWith("ms")
            ? new ParseHelper(sValue, 1, 1000)
            :  original; // bypass
}

private ParseHelper setupIfMillisecond(ParseHelper original) {
    final String sValue = original.source;
    return sValue.endsWith("ms")
            ? new ParseHelper(sValue, 2, 1)
            : original; // bypass
}

// and so on...
</code>```

Based on above building blocks, code of your method could look as follows:

```<code>public long parseTimeValue(String sValue) {

   return setupIfSecond(
           setupIfMillisecond(
           setupIfInSecond(
           setupIfInMinute(
           setupIfHour(
           setupIfDay(
           setupIfWeek(
           new ParseHelper(sValue, 0, 1))))))))
           .invoke();
}
</code>```

You see, there's no complexity left over, no curly braces inside the method at all (nor multiple returns like in my original brute force suggestion on flattening code). You just sequentially check the input and adjust the processing as needed.

Body:
Since you return millis at the end of that awful ifelseifelse anyway, first thing that comes to mind is to return the value immediately from within if-blocks. This approach follows one that is listed in catalog of refactoring patterns as Replace Nested Conditional with Guard Clauses.

A method has conditional behavior that does not make clear what the normal path of execution is

Use Guard Clauses for all the special cases

It will help you get rid of else's, flatten the code and make Sonar happy:

    if (sValue.endsWith("S")) {
        return new ExtractSecond(sValue).invoke();
    } // no need in else after return, code flattened

    if (sValue.endsWith("ms")) {
        return new ExtractMillisecond(sValue).invoke();
    }

    // and so on...
    return Long.parseLong(sValue); // forget millis, these aren't needed anymore

Another thing worth considering is dropping the try-catch block. This will also lower cyclomatic complexity, but main reason why I recommend it is that with this block, there is no way for caller code to distinguish legally parsed 0 from number format exception.

Unless you're 200% certain that returning 0 for parse errors is what caller code needs, you better propagate that exception up and let caller code decide how to deal with it. It is typically more convenient to decide at caller whether to abort execution or retry getting input, or fall back to some default value like 0 or -1 or whatever.

Your code snippet for an example ExtractHour makes me feel that ExtractXXX functionality is designed in a way far from optimal. I bet every of the remaining classes thoughtlessly repeats same parseDouble and substring, and multiplying stuff like 60 and 1000 over and over and over again.

This is because you missed the essence of what needs to be done depending on sValue - namely, it defines how much chars to cut from the end of the string and what would be the multiplier value. If you design your "core" object around these essential features, it would look like as follows:

private static class ParseHelper {
    // three things you need to know to parse:
    final String source;
    final int charsToCutAtEnd;
    final long multiplier;

    ParseHelper(String source, int charsToCutAtEnd, long multiplier) {
        this.source = source == null ? "0" : source; // let's handle null here
        this.charsToCutAtEnd = charsToCutAtEnd;
        this.multiplier = multiplier;
    }

    long invoke() {
        // NOTE consider Long.parseLong instead of Double.parseDouble here
        return (long) (Double.parseDouble(cutAtEnd()) * multiplier);
    }

    private String cutAtEnd() {
        if (charsToCutAtEnd == 0) {
            return source;
        }
        // write code that cuts 'charsToCutAtEnd' from the end of the 'source'
        throw new UnsupportedOperationException();
    }
}

After that, you'd need a code that configures above objects per particular condition if it is met, or somehow "bypasses" otherwise. This could be done about as follows:

private ParseHelper setupIfInSecond(ParseHelper original) {
    final String sValue = original.source;
    return sValue.endsWith("s") && !sValue.endsWith("ms")
            ? new ParseHelper(sValue, 1, 1000)
            :  original; // bypass
}

private ParseHelper setupIfMillisecond(ParseHelper original) {
    final String sValue = original.source;
    return sValue.endsWith("ms")
            ? new ParseHelper(sValue, 2, 1)
            : original; // bypass
}

// and so on...

Based on above building blocks, code of your method could look as follows:

public long parseTimeValue(String sValue) {

   return setupIfSecond(
           setupIfMillisecond(
           setupIfInSecond(
           setupIfInMinute(
           setupIfHour(
           setupIfDay(
           setupIfWeek(
           new ParseHelper(sValue, 0, 1))))))))
           .invoke();
}

You see, there's no complexity left over, no curly braces inside the method at all (nor multiple returns like in my original brute force suggestion on flattening code). You just sequentially check the input and adjust the processing as needed.


答:
I'm going to quote the advice Microsoft gives for namespaces (.NET's packages), which doesn't have the domain name convention. I think it's good advice for Java packages too, since I don't believe that a domain name represents a solid and stable identity.

The general format for a namespace name is as follows:

<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]

For example, Microsoft.WindowsMobile.DirectX.

Do prefix namespace names with a company name to prevent namespaces from different companies from having the same name and prefix.

Do use a stable, version-independent product name at the second level of a namespace name.

Do not use organizational hierarchies as the basis for names in namespace hierarchies, because group names within corporations tend to be short-lived.

The namespace name is a long-lived and unchanging identifier. As organizations evolve, changes should not make the namespace name obsolete.

If even your company name is unstable, you might want to just start with the product name.

Title: Is the Java package name convention flawed?

Body:
We're all familiar with the Java package name convention of turning the domain name around. I.e. www.evilcorp.com would, by convention, chose to have their java packages com.evilcorp.stuff.

Increasingly I'm getting fed up with this. As a commercial programmer, I encounter time and again that the software package name is completely irrelevant due to some rebrand, acquisition or similar.

In the opensource world there's less name changes so there it makes sense. However it seems to me the shelf life of many pieces of (commercial/internal) software are much longer than that of the organisation making them.

The problem is often made worse by software projects taking the marketing department's lead to use the name du jour they use refer to a certain project. A name that will, without fail, change 3 months down the line to make the emperor's new clothes feel fresh and new.

Because of this, I've mostly stopped using the reverse domain as package name. Granted, if this is done on a large scale, there's risk of name collisions, but surely this is mitigated by either using "unique" software names, avoiding generic words, or use the reverse domain for projects intended to be sold/released as libraries.

Other thoughts?


问:
Should a class know about its subclasses?
Should a class know about its subclasses? Should a class do something that is specific for a given subclass for instance?

My instincts tells me that is a bad design, it seems like an anti-pattern of some sort.

答:
The answer implied by the concept of classes is "no".

Either whatever action, data or relation you're handling is part of all subclasses - then it should be handled in the superclass without checking the actual type. Or it applies only to some subclasses - then you'd have to perform run-time type checks to do the right thing, the superclass would have to be changed whenever someone else inherits from it (or it might silently do the wrong thing), changes in the derived classes can break the unchanged superclass, etc.

In short, you get a number of bad consequences which are usually bad enough to reject such solutions out of hand. If several of your subclasses do the same thing and you want to avoid code duplication (practically always a good thing), a better solution is to introduce a mid-level class from which all those subclasses can inherit the code.


答:
I like all three ways of doing it, and the length of code would tell me how it should be organized.  I don't mind two or three pages of code in my Application object.  Once it gets to be more than that, I like to see more effort put into separating responsibilities of classes.

The application should either contain the entire code, or only be a boot-strapping to allow the application to run.  That is, it should create your controller and views, and then not be involved in the main body of the application.  Shutdown or exceptional errors would be nice to contain within the Application class.

In the case where the application is a short-term worker, it does come down to code-size for me.

Title: Which one of these designs is preferred?

Body:
In the case of an application with a single simple responsibility (eg, a simple replacement for grep or wc), which of these designs is preferred and why? I find that they are all testable and they all do their job. Does any of them have any significant advantages over the other?

1: All methods in the main class:

```<code>public class App {
    public static void main(String[] args)
    {
        App app = new App();
        AppInput input = app.readInput();
        AppOutput output = app.processInputToOutput(input);
        app.writeOutput(output);
    }

    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}
</code>```

2: Basic methods in a separate class, main class only making calls to read and process input, and output result:

```<code>public class App {
    public static void main(String[] args)
    {
        AppWorker worker = new AppWorker();
        AppInput input = worker.readInput();
        AppOutput output = worker.processInputToOutput(input);
        worker.writeOutput(output);
    }
}

public class AppWorker {
    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }
}
</code>```

3: Have all the work in a separate worker class, with the main class only instantiating the worker and triggering it to do its work:

```<code>public class App {
    public static void main(String[] args)
    {
        AppWorker worker = new AppWorker();
        worker.doYourWork();
    }
}

public class AppWorker {
    public void doYourWork()
    {
        AppInput input = readInput();
        AppOutput output = processInputToOutput(input);
        writeOutput(output);
    }

    public AppInput readInput() { .. }
    public AppOutput processInputToOutput(AppInput input) { .. }
    public void writeOutput(AppOutput output) { .. }

}
</code>```


答:
Not only should it not know, it simply can't! Usually, a class can be extended anytime, anywhere. It can be extended by classes that didn't even exist when it was written.

Some languages allow extending classes to be controlled by the superclass. In Scala, a class can be marked as sealed, which means that it can only by extended by other classes within the same compilation unit (source file). However, unless those subclasses are also sealed or final, the subclasses can then be further extended by other classes.

In Scala, this is used to model closed algebraic data types, so the canonical Haskell List type:

```<code>data List a = Nil | Cons a (List a)
</code>```

can be modeled in Scala like this:

```<code>sealed trait List[+A]

case object Nil extends List[Nothing]

final case class Cons[+A] extends List[A]
</code>```

And you can guarantee that only those two sub-"classes" exist because List is sealed and thus cannot be extended outside of the file, Cons is final and thus cannot be extended at all and Nil is an object which cannot be extended anyway.

But this is a specific use case (modeling algebraic data types via inheritance) and even in this case, the superclass doesn't actually know about its subclasses. It's more a guarantee to the user of the List type that if he does a case discrimination of Nil and Cons, there won't be any other alternative popping up behind his back.

Body:
Should a class know about its subclasses? Should a class do something that is specific for a given subclass for instance?

My instincts tells me that is a bad design, it seems like an anti-pattern of some sort.

Body:
Not only should it not know, it simply can't! Usually, a class can be extended anytime, anywhere. It can be extended by classes that didn't even exist when it was written.

Some languages allow extending classes to be controlled by the superclass. In Scala, a class can be marked as sealed, which means that it can only by extended by other classes within the same compilation unit (source file). However, unless those subclasses are also sealed or final, the subclasses can then be further extended by other classes.

In Scala, this is used to model closed algebraic data types, so the canonical Haskell List type:

data List a = Nil | Cons a (List a)

can be modeled in Scala like this:

sealed trait List[+A]

case object Nil extends List[Nothing]

final case class Cons[+A] extends List[A]

And you can guarantee that only those two sub-"classes" exist because List is sealed and thus cannot be extended outside of the file, Cons is final and thus cannot be extended at all and Nil is an object which cannot be extended anyway.

But this is a specific use case (modeling algebraic data types via inheritance) and even in this case, the superclass doesn't actually know about its subclasses. It's more a guarantee to the user of the List type that if he does a case discrimination of Nil and Cons, there won't be any other alternative popping up behind his back.


答:
The convention is not flawed. People are flawed, as you have nicely illustrated yourself.

I can think of 2 benefits:

It avoids collision between independent developers. A domain is unique. Two people can name two different project the same, but a domain has exactly one owner.

It makes it easier to find the maintainer. If you inherit a code base, that uses some open source library, it better be in a package that helps you find it. By now it doesn't really matter, because you will most certainly be able to google it. But 10 years ago, this wasn't so evident.


答:
I recommend doing the all-in-one, then refactor into separate classes as the application grows.  There's no need to add complexity into the design until it's needed.  How you split it later depends on how your application is growing:

Different types of input.  Maybe you're reading from a String or a network stream instead of a file.   In this case, you want to create classes and/or interfaces on the input and instantiate them from main.

Different types of output. Maybe you're outputting to a database or a web page instead of a terminal. In this case, you want to create classes and/or interfaces on the output and instantiate them from main.

Different kinds of processing.  In this case, you want classes and/or interfaces for the processing step and instantiate those from main.

Different kinds of main tasks. Maybe you're adding a GUI option.  In this case, your separate AppWorker idea to do the entire thing is a good refactor, because you can make an AppWorkerCli and an AppWorkerGUI.

Some people try to avoid any rearchitecting by guessing how the application will grow, but in my experience, developers are poor guessers.


答:
Yes, sometimes. For example, when there is a limited number of subclasses exist. A visitor pattern is an illustration of usefulness of this approach.

Example: an abstract syntax tree (AST) nodes of some well-defined grammar can all be inherited from a single Node class implementing a visitor pattern to handle all node types.

Title: Should a class know about its subclasses?


答:
If I write a component for a firm and later, after I've left, someone extends it for their own purposes should I be informed about that?

No!

Same with classes. Trust your instincts.


答:
JSON is just a data-interchange format based on JavaScript.

REST is an architecture style whereas OData is a specific implemenation of REST designed to generate and consume data, which supports two formats, AtomPub and JSON.

So the difference between JSON with plain REST and OData are the options in OData for data manipulation eg, if we query data using OData protocol, we can specify the below options in the URI,

$orderby

$top

$skip

$filter

$format

$select

We can do projection, link the resources, etc. and all these options are available out of the box. Now imagine if we had to provide all these features in our own REST service then we would have to,

Implement all of them

Create our own convention/keywords for different operations

It is not only lot of work but also leads to inconsistencies and creates a learning curve for our data consumers.

Title: What is the need of Odata when I have JSON?

Body:
I am trying to understand the point of Odata and when it would make sense. Right now how I work is I use ASP.NET and MVC/WebApi controller to serialize/deserialize objects into JSON and have javascript do something with it.

From what I can tell the benefit of OData is being able to query directly from the URL ... But since I am writing the client and server code there is no need for that.

Would anyone ever parse the results of a ODaya query in javascript??

Maybe OData is more about providing a generic endpoint for ALL clients to get detailed information from a query that JSON does not provide ? So if I was a provider of data then I suppose that is what odata is for ?

Help me understand the purpose and use of REST/JSON/ODATA.


答:
First, Look at your question from the client's perspective.

They don't necessarily know you, your work ethic, or the quality of your code.  Maybe they have a referral from someone they trust, but in many ways you are an unknown to them.

And then think about why they are interviewing you.  They have a problem that needs to be solved; they need some code written or modified to support their business.

Keep in mind that they are asking for a sample in order to help answer those unknowns.

So what sort of a sample should you provide them?

The short answer is to provide them with a sample that comes as close as possible to matching their expectations.

The longer answer is that this can mean:

Nothing that's proprietary.  If you send them a previous client's code then they'll know you'll do the same thing with their code.

Code that's in their preferred language.  Don't send them a Java sample when they're working in C#.

Code that's in the same segment of the application stack.  Don't send UI code if they need a service written.  Likewise, don't send a database access / ORM piece if they need a visual.

Code that matches their likely request.  Do they need maintenance?  Show them a before / after picture and show how you made the requested changes within that project.  Do they need a complete project?  Then provide them with a small sample that mirrors everything that you would be providing as part of the contract.

Code that matches their business domain.  Are they in product sales or perhaps services?  Find a sample project that did the same or similar type of a thing.

As a freelancer, your code sample is a piece of your coding portfolio.  Just like an artist, you need a catalog of previous work to show what it is that you can create.  Working on open source projects can be one source of samples.  You can also point to your StackExchange profile to help show some of your thought processes and communication skills.

Clients generally want a sample that they can dig through on their own.  If they need a walk-through (via Skype) in order to understand the code, it may give the impression that they won't be able to maintain the code later on.  If you generally provide documentation along with your contract work, I would include relevant samples of your documentation along with the code sample you provide.

Title: What to send when a client wants a sample of my code to test my qualities?

Body:
We've all faced this. You apply to a cool project and they ask you to send them a piece of your code. On the surface, this look OK and I am fine with it.

But what shall I send them? My cool utility? Snapshot of structure in complex project? Something else?

So far, I have tried to persuade them to have a desktop share via Skype and that I lead them through code and structure. But somehow clients do not like this approach.

So I'd like to hear your thoughts.


问:
How to present code in academic work?
Actually, I'm writing my undergrad thesis, that consists in analysing the BitTorrent algorithm and see its application on Transmission client as an example of implementation.

Reading through its code, written in C, you can see many layers of functions

```<code>static const char*
tr_metainfoParseImpl (const tr_session  * session,
                      tr_info           * inf,
                      bool              * hasInfoDict,
                      int               * infoDictLength,
                      const tr_variant     * meta_in)
{
  int64_t i;
  size_t len;
  const char * str;
  const uint8_t * raw;
  tr_variant * d;
  tr_variant * infoDict = NULL;
  tr_variant * meta = (tr_variant *) meta_in;
  bool b;
  bool isMagnet = false;

  /* info_hash: urlencoded 20-byte SHA1 hash of the value of the info key
   * from the Metainfo file. Note that the value will be a bencoded
   * dictionary, given the definition of the info key above. */
  b = tr_variantDictFindDict (meta, TR_KEY_info, &infoDict);
  if (hasInfoDict != NULL)
    *hasInfoDict = b;

  if (!b)
    {
      /* no info dictionary... is this a magnet link? */
      if (tr_variantDictFindDict (meta, TR_KEY_magnet_info, &d))
        {
        (...)
</code>```

tr_metainfoParseImpl() is the function called after we add a .torrent by file or magnet link. It calls tr_variantDictFindDict() to find some string "info" somewhere in the metadata dictionary, in order to get information about that torrent file.

Algoritmically, it has no value to me, since I want to emphasize other aspects of BitTorrent algorithm other than string search, although I want to leave its caller line there just to illustrate it's happenning.

The function tr_variantDictFindDict() and its child are

```<code>bool // func1
tr_variantDictFindDict (tr_variant       * dict,
                        const tr_quark     key,
                        tr_variant      ** setme)
{
  return tr_variantDictFindType (dict, key, TR_VARIANT_TYPE_DICT, setme);
}

static bool // func2
tr_variantDictFindType (tr_variant      * dict,
                        const tr_quark    key,
                        int               type,
                        tr_variant     ** setme)
{
  return tr_variantIsType (*setme = tr_variantDictFind (dict, key), type);
}
</code>```

As we can see, although this may exist for code engineering reasons, algorithmically it has no value.

So, I'm looking for reasonable, feasible, practical ways to avoid showing this kind of code in my work.

Using the code above as an example, I thought some options:

put the relevant part of func1 caller function, showing the line calling func1, and after that showing func2 callee (in which will have the another relevant part of code.

putting func1 caller code and func2 callee "side by side", as if they were in one big function

literate programming from the beginning

Please, feel free to share your experiences with this situation. Also, please change the SX site if needed, although I looked for the best SX site to ask this question and this one seemed legit.

答:
For my graduate thesis, I had a similar challenge and spent some time reflecting about what it was I was trying to accomplish.

Putting a non-trivial amount of code in printed form brings up several challenges.

Code is best examined and manipulated in electronic form, so how do you provide that maneuverability within the printed page?

Quite a bit of the code is irrelevant to the problem at hand.  File IO, memory manipulation, error handling, etc... are all examples of things that have to be in the code but don't support the thesis itself.

You want / need to provide all of the code so a future student can pick up your research and continue the work.  In addition, the University expects all of the code so they can demonstrate you actually did the work and validate your results.

My thesis involved taking an existing algorithm, refining it for performance, and then extending the algorithm to a new set of use cases.

Within the body of my thesis, I placed only the relevant portions of the old and new routines side by side in order to provide a measure of comparison.  Within the text, I then explained the differences between the functions and the measurable differences that I had found.  I would then include appropriate charts / graphs / illustrations along with the explanation to help support the point I was making.

In some cases, I had refactored the existing code into new functions.  Sometimes it made sense to include the refactored out sections of code within the discourse and sometimes it didn't.

Think of your thesis as a narrative. Don't include anything that doesn't directly contribute to the point you need to be making within each section.  Your thesis will be long enough as it is, and you don't want to overload the reader with unnecessary or irrelevant detail.  This aspect was crucial for me as several of my advisers didn't care as much about the code and wanted to focus on the results.

The last aspect to consider is where to include the complete source listing.  I placed my source in an appendix at the end of my thesis.  I also included some explanatory text on compilation and running the program so others could validate what I had done.  Since I had some test sets of data that were necessary to recreate what I had done they were included too in the appendix.

Title: How to present code in academic work?


答:
Given that things like

```<code>std::string myString = "Hello, world!";
</code>```

are perfectly valid, it seems rather obvious to me why there is confusion.

Title: Why do people confuse C-type strings and STL strings

Body:
The last week I saw at least three questions where people were confused about the differences between char * and std::string or made some related mistakes.

Don't get me wrong, I don't have a problem with this, I just don't get the exact reason for this. Maybe it was just a coincidence.

Body:
Given that things like

std::string myString = "Hello, world!";

are perfectly valid, it seems rather obvious to me why there is confusion.


问:
Are expensive operations for a user bad for other users?
Let's say user A does something expensive (regarding CPU and/or memory), which takes a few seconds. Concurrently, user B needs a very small amount of computing time.

In this case, will the computing for user A significantly slow down that of user B (even block maybe?), or are these situations handled in most systems?

(I use ASP.NET MVC, but I wouldn't mind a more general answer either)

答:
This is more of a systems administration question. Assuming the processes were the same priority in the system, the higher resource process wouldn't starve the other one, but it might run into issues if it needed to grow its resources.

There are resources on the system side that you can use to control the impact of high-utilization processes, which would be something to explore if your users start complaining.