问:
Is there an effective way for creating complex forms?
While creating a 'search' form I've been faced to an overwhelming complexity and I was wondering whether there is a well-known way to accomplish such task.

Fields of the form in question can be seen here: http://developer.echonest.com/docs/v4/artist.html#search

Here are a few issues I've been faced to and tried to solve with simple solutions though it led to a lot of copying and pasting in the end :

When the user can select multiple choices for a field or not, I systematically had to create a collection of them, adding a 'null' value for the ability of ignoring that field. Also, as these are enumeration values they are not user-friendly to read and therefore needed an extra description field that will be shown instead on the UI. And at the end all this user-friendly values need to be converted back to the original object.

Selection being made by the user, these choices need to be retrieved and for this, unfortunately in my case WPF data binding shown its limits. Example : when a user chooses items from a collection, there is no way to update the target object with these selections. (Obviously this is unrealistic as the object serves as a data source)

In the end it resumes to a lot of manual fetching from combo boxes, list boxes etc ... a middle-man object to receive all that and to this you have to add validation as well.

A strategy therefore becomes imperative as I will have to realise a couple of these complex forms.

I've been searching the web for solutions but beside extremely simple examples I found nothing relevant.

So the question is, is there an effective way that helps when creating complex user forms ?

答:
I've sorted it out and in the end it went pretty well so I'll give here my recommendations according this painful experience.

(these tips apply for WPF)

Validation : use INotifyDataErrorInfo instead of rules in XAML, your validation takes place in the object instead and even it's sort of complicate to setup it is really worth it. This interface is appropriate for validation of a complex object. Here's an excellent article showing it : http://anthymecaillard.wordpress.com/2012/03/26/wpf-4-5-validation-asynchrone/ I'd suggest you to not copy/paste it but write it manually. (I did and it took me less time than copy/paste and trying to grasp what it does later)

Updating your object whenever user inputs values : it's clearly better to do nothing during controls events such as TextChanged but to stick to validation as mentioned above. Hook to Validation.Error events of your controls for managing the logic of your API (in my case when 'name' is set the user cannot search by 'familiarity' so I disabled appropriate controls).

That leds to a search button that gets enabled only when all values are correct and this is actually the place where you'd grab all params and your stuff, all in one place, not scattered anymore through events of controls.

Also, do not hesitate to use a middle-man object even though it won't contain all the fields of the original object it still proved to be helpful as that's where I implemented INotifyDataDataErrorInfo. There was absolutely no way that I modify the source object which is fine and part of a library anyway ! For multiple choices a user can do on a ListBox, I didn't use it, I just populated them and that's it. (they are all valid by nature, in my case)

Now a few screenshots and explanations.

Here's the API, not about 2 or 3 fields but 21, when I saw it first I knew it would be a pain to implement but still I underestimated it ...

Here the search button gets enabled only when validation is correct,

Using an extremely simple method, luckily in my case only these 3 cases were needed.

    private void ToggleSearch()
    {
        var b1 = GetHasErrorPropertyValue(TextBoxArtistLocation);
        var b2 = GetHasErrorPropertyValue(TextBoxDescription);
        var b3 = GetHasErrorPropertyValue(TextBoxName);
        ButtonSearch.IsEnabled = !(b1 || b2 || b3);
    }

    private static bool GetHasErrorPropertyValue(DependencyObject dependencyObject)
    {
        if (dependencyObject == null) throw new ArgumentNullException("dependencyObject");
        return (bool)dependencyObject.GetValue(Validation.HasErrorProperty);
    }

    // Hooking to Validation.Error attached property, these boxes all point to here.
    private void TextBox_OnError(object sender, ValidationErrorEventArgs e)
    {
        ToggleSearch();
    }
```

<p>Here's the output of the query, well the only bothering stuff compared to previous version is that for testing I have to search every time to see the result of the built query for which I assigned Alt-S as a time-saver. Previously I was fetching the result on each value changed in each control, while it looked simple as these were 5 lines methods it soon went to a nightmare. With the new method, I have one hand setting the fields with mouse the other pressing Alt-S and obviously a much simpler class to understand/use/debug. </p>

<p><img src="https://i.stack.imgur.com/VW9ME.png" alt="enter image description here"></p>

<p>Last screen : as you can see there isn't much in it, the 3 top methods each call one of the methods below, I think they are self-explanatory. The helper methods are used for setting/retrieving values from controls and to form the query.</p>

<p><img src="https://i.stack.imgur.com/duMoX.png" alt="enter image description here"></p>

<p>Last two samples :</p>

<p>Populating data :</p>

<pre class="lang-cs prettyprint-override"><code>    private async Task PopulateData()
    {
        string apiKey = App.GetApiKey();

        var years = GetDescribedEnum<ArtistSearchYear>().ToList();
        ComboBoxArtistEndYearAfter.ItemsSource = years;
        ComboBoxArtistEndYearBefore.ItemsSource = years;
        ComboBoxArtistStartYearAfter.ItemsSource = years;
        ComboBoxArtistStartYearBefore.ItemsSource = years;

        var rankTypes = GetDescribedEnum<ArtistSearchRankType>().ToList();
        ComboBoxRankType.ItemsSource = rankTypes;

        var results = Enumerable.Range(0, 101).Select(s => s.ToString(CultureInfo.InvariantCulture)).ToList();
        results.Insert(0, string.Empty);
        ComboBoxResults.ItemsSource = results;

        var sort = GetDescribedEnum<ArtistSearchSort>().OrderBy(s => s.Description).ToList();
        ComboBoxSort.ItemsSource = sort;

        var start = Enumerable.Range(0, 3).Select(s => (s * 15).ToString(CultureInfo.InvariantCulture)).ToList();
        start.Insert(0, string.Empty);
        ComboBoxStart.ItemsSource = start;

        var buckets = GetDescribedEnum<ArtistSearchBucket>().OrderBy(s => s.Description).ToList();
        ListBoxBuckets.ItemsSource = buckets;

        var genres = await Queries.ArtistListGenres(apiKey);
        ListBoxGenre.ItemsSource = genres.Genres.Select(s => s.Name);

        var styles = await Queries.ArtistListTerms(apiKey, ArtistListTermsType.Style);
        ListBoxStyle.ItemsSource = styles.Terms.Select(s => s.Name);

        var moods = await Queries.ArtistListTerms(apiKey, ArtistListTermsType.Mood);
        ListBoxMood.ItemsSource = moods.Terms.Select(s => s.Name);
    }
</code>```

Retrieving parameters :

    private void RunSearch()
    {
        var parameters = new ArtistSearchParameters();

        var year = (Func<ComboBox, ArtistSearchYear?>)((c) =>
            {
                if (c.SelectedValue == null) return null;
                var value = GetDescribedObjectValue<ArtistSearchYear>(c.SelectedValue);
                return value == ArtistSearchYear.Invalid ? (ArtistSearchYear?)null : value;
            });
        parameters.ArtistEndYearAfter = year(ComboBoxArtistEndYearAfter);
        parameters.ArtistEndYearBefore = year(ComboBoxArtistEndYearBefore);
        parameters.ArtistStartYearAfter = year(ComboBoxArtistStartYearAfter);
        parameters.ArtistStartYearBefore = year(ComboBoxArtistStartYearBefore);

        if (ComboBoxRankType.SelectedValue == null)
        {
            parameters.RankType = null;
        }
        else
        {
            var value = GetDescribedObjectValue<ArtistSearchRankType>(ComboBoxRankType.SelectedValue);
            parameters.RankType = value == ArtistSearchRankType.Invalid ? (ArtistSearchRankType?)null : value;
        }

        var selectedValue = ComboBoxSort.SelectedValue;
        if (selectedValue == null)
        {
            parameters.Sort = null;
        }
        else
        {
            var value = GetDescribedObjectValue<ArtistSearchSort>(selectedValue);
            parameters.Sort = value == ArtistSearchSort.Invalid ? (ArtistSearchSort?)null : value;
        }

        parameters.Start = StringToNullableInt(GetSelectorValue<string>(ComboBoxStart));
        parameters.Results = StringToNullableInt(GetSelectorValue<string>(ComboBoxResults));

        parameters.MaxFamiliarity = SliderMaxFamiliarity.Value < 1.0d ? (double?)SliderMaxFamiliarity.Value : null;
        parameters.MinFamiliarity = SliderMinFamiliarity.Value > 0.0d ? (double?)SliderMinFamiliarity.Value : null;
        parameters.MaxHotttnesss = SliderMaxHottness.Value < 1.0d ? (double?)SliderMaxHottness.Value : null;
        parameters.MinHotttnesss = SliderMinHottness.Value > 0.0d ? (double?)SliderMinHottness.Value : null;

        if (CheckBoxFuzzyMatch.IsChecked.HasValue)
            parameters.FuzzyMatch = CheckBoxFuzzyMatch.IsChecked.Value ? (bool?)true : null;
        if (CheckBoxLimit.IsChecked.HasValue)
            parameters.Limit = CheckBoxLimit.IsChecked.Value ? (bool?)true : null;

        var buckets =
            GetSelectedItems<DescribedObject<ArtistSearchBucket>>(ListBoxBuckets)
                          .OrderBy(s => s.Description)
                          .Select(s => s.Value)
                          .ToList();
        parameters.Buckets = buckets.Count > 0 ? buckets : null;
        var genres = GetSelectedItems<string>(ListBoxGenre).OrderBy(s => s).ToList();
        parameters.Genres = genres.Count > 0 ? genres : null;
        var moods = GetSelectedItems<string>(ListBoxMood).OrderBy(s => s).ToList();
        parameters.Moods = moods.Count > 0 ? moods : null;
        var style = GetSelectedItems<string>(ListBoxStyle).OrderBy(s => s).ToList();
        parameters.Styles = style.Count > 0 ? style : null;

        parameters.ArtistLocation = string.IsNullOrEmpty(TextBoxArtistLocation.Text)
                                        ? null
                                        : TextBoxArtistLocation.Text;
        parameters.Description = string.IsNullOrEmpty(TextBoxDescription.Text)
                                     ? null
                                     : Regex.Split(TextBoxDescription.Text, @", ?")
                                            .Where(s => !string.IsNullOrWhiteSpace(s))
                                            .ToList();
        if (string.IsNullOrEmpty(TextBoxName.Text))
        {
            parameters.Name = null;
        }
        else
        {
            parameters.Name = TextBoxName.Text;
            parameters.MaxFamiliarity = null;
            parameters.MaxHotttnesss = null;
            parameters.MinFamiliarity = null;
            parameters.MinHotttnesss = null;
        }

    }
```

<p>In my case nullables were vital as they allowed me to discard values when building the query.</p>

<p>For building the query I cheated somehow using JSON :</p>

<pre class="lang-cs prettyprint-override"><code>    protected static string GetUrlParameters(string json)
    {
        if (json == null) throw new ArgumentNullException("json");
        JsonTextReader reader = new JsonTextReader(new StringReader(json));
        string path = string.Empty;
        List<string> list = new List<string>();
        while (reader.Read())
        {
            JsonToken type = reader.TokenType;
            if (type == JsonToken.PropertyName)
            {
                path = reader.Path;
            }
            else
            {
                bool b0 = type == JsonToken.Integer;
                bool b1 = type == JsonToken.Float;
                bool b2 = type == JsonToken.String;
                bool b3 = type == JsonToken.Boolean;
                if (b0 || b1 || b2 || b3)
                {
                    var value = reader.Value.ToString();
                    if (b3) value = value.ToLower();

                    string item = string.Format("{0}={1}", path, value);
                    list.Add(item);
                }
            }
        }
        return string.Join("&", list);
    }
</code>```

DescribedObject is a middle-man object that holds the desired value and the description is fetched from a value [DescriptionAttribute]

public class DescribedObject
{
    private readonly string _description;
    private readonly Object _value;

    public DescribedObject() // NOTE : for design-time
    {

    }
    protected DescribedObject(Object value, string description)
    {
        _value = value;
        _description = description;
    }

    public string Description
    {
        get { return _description; }
    }

    public Object Value
    {
        get { return _value; }
    }

    public override string ToString()
    {
        return string.Format("Value: {0}, Description: {1}", _value, _description);
    }
}

public class DescribedObject<T> : DescribedObject
{

    public DescribedObject(T value, string description)
        : base(value, description)
    {
    }
    public new T Value
    {
        get
        {
            return (T)base.Value;
        }
    }
}
```

<p>A described object :</p>

<pre class="lang-cs prettyprint-override"><code>[JsonConverter(typeof(PropertyEnumConverter))]
public enum ArtistSearchYear
{
    [Description(null), JsonProperty(null)]
    Invalid = 0,
    [Description("1970"), JsonProperty("1970")]
    Year1970,
    [Description("1971"), JsonProperty("1971")]
    Year1971
}
</code>```

(PropertyEnumConverter is a simple object that will convert these values according their JsonProperty attribute.)

So as you can see, I kept it stupidly simple but it took me some time as at first I had a more complex approach, again the simplicity proven really helpful though it sounds stupid sometimes.

I haven't talked about the XAML side, briefly there's absolutely nothing in it beside controls and templates, only bindings have these two properties set for them to validate. (also, the object implements INotifyPropertyChanged)

<TextBox x:Name="TextBoxArtistLocation"
            Style="{StaticResource TextBoxInError}"
            Validation.Error="TextBox_OnError"
            Text="{Binding ArtistLocation, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" />
```

I hope this answer will help someone, I've tried to be as concise as possible but if you have any question/comment, ask below.

Body:
I've sorted it out and in the end it went pretty well so I'll give here my recommendations according this painful experience.

(these tips apply for WPF)

Validation : use INotifyDataErrorInfo instead of rules in XAML, your validation takes place in the object instead and even it's sort of complicate to setup it is really worth it. This interface is appropriate for validation of a complex object. Here's an excellent article showing it : http://anthymecaillard.wordpress.com/2012/03/26/wpf-4-5-validation-asynchrone/ I'd suggest you to not copy/paste it but write it manually. (I did and it took me less time than copy/paste and trying to grasp what it does later)

Updating your object whenever user inputs values : it's clearly better to do nothing during controls events such as TextChanged but to stick to validation as mentioned above. Hook to Validation.Error events of your controls for managing the logic of your API (in my case when 'name' is set the user cannot search by 'familiarity' so I disabled appropriate controls).

That leds to a search button that gets enabled only when all values are correct and this is actually the place where you'd grab all params and your stuff, all in one place, not scattered anymore through events of controls.

Also, do not hesitate to use a middle-man object even though it won't contain all the fields of the original object it still proved to be helpful as that's where I implemented INotifyDataDataErrorInfo. There was absolutely no way that I modify the source object which is fine and part of a library anyway ! For multiple choices a user can do on a ListBox, I didn't use it, I just populated them and that's it. (they are all valid by nature, in my case)

Now a few screenshots and explanations.

Here's the API, not about 2 or 3 fields but 21, when I saw it first I knew it would be a pain to implement but still I underestimated it ...

Here the search button gets enabled only when validation is correct,

Using an extremely simple method, luckily in my case only these 3 cases were needed.

    private void ToggleSearch()
    {
        var b1 = GetHasErrorPropertyValue(TextBoxArtistLocation);
        var b2 = GetHasErrorPropertyValue(TextBoxDescription);
        var b3 = GetHasErrorPropertyValue(TextBoxName);
        ButtonSearch.IsEnabled = !(b1 || b2 || b3);
    }

    private static bool GetHasErrorPropertyValue(DependencyObject dependencyObject)
    {
        if (dependencyObject == null) throw new ArgumentNullException("dependencyObject");
        return (bool)dependencyObject.GetValue(Validation.HasErrorProperty);
    }

    // Hooking to Validation.Error attached property, these boxes all point to here.
    private void TextBox_OnError(object sender, ValidationErrorEventArgs e)
    {
        ToggleSearch();
    }

Here's the output of the query, well the only bothering stuff compared to previous version is that for testing I have to search every time to see the result of the built query for which I assigned Alt-S as a time-saver. Previously I was fetching the result on each value changed in each control, while it looked simple as these were 5 lines methods it soon went to a nightmare. With the new method, I have one hand setting the fields with mouse the other pressing Alt-S and obviously a much simpler class to understand/use/debug.

Last screen : as you can see there isn't much in it, the 3 top methods each call one of the methods below, I think they are self-explanatory. The helper methods are used for setting/retrieving values from controls and to form the query.

Last two samples :

Populating data :

    private async Task PopulateData()
    {
        string apiKey = App.GetApiKey();

        var years = GetDescribedEnum<ArtistSearchYear>().ToList();
        ComboBoxArtistEndYearAfter.ItemsSource = years;
        ComboBoxArtistEndYearBefore.ItemsSource = years;
        ComboBoxArtistStartYearAfter.ItemsSource = years;
        ComboBoxArtistStartYearBefore.ItemsSource = years;

        var rankTypes = GetDescribedEnum<ArtistSearchRankType>().ToList();
        ComboBoxRankType.ItemsSource = rankTypes;

        var results = Enumerable.Range(0, 101).Select(s => s.ToString(CultureInfo.InvariantCulture)).ToList();
        results.Insert(0, string.Empty);
        ComboBoxResults.ItemsSource = results;

        var sort = GetDescribedEnum<ArtistSearchSort>().OrderBy(s => s.Description).ToList();
        ComboBoxSort.ItemsSource = sort;

        var start = Enumerable.Range(0, 3).Select(s => (s * 15).ToString(CultureInfo.InvariantCulture)).ToList();
        start.Insert(0, string.Empty);
        ComboBoxStart.ItemsSource = start;

        var buckets = GetDescribedEnum<ArtistSearchBucket>().OrderBy(s => s.Description).ToList();
        ListBoxBuckets.ItemsSource = buckets;

        var genres = await Queries.ArtistListGenres(apiKey);
        ListBoxGenre.ItemsSource = genres.Genres.Select(s => s.Name);

        var styles = await Queries.ArtistListTerms(apiKey, ArtistListTermsType.Style);
        ListBoxStyle.ItemsSource = styles.Terms.Select(s => s.Name);

        var moods = await Queries.ArtistListTerms(apiKey, ArtistListTermsType.Mood);
        ListBoxMood.ItemsSource = moods.Terms.Select(s => s.Name);
    }

Retrieving parameters :

    private void RunSearch()
    {
        var parameters = new ArtistSearchParameters();

        var year = (Func<ComboBox, ArtistSearchYear?>)((c) =>
            {
                if (c.SelectedValue == null) return null;
                var value = GetDescribedObjectValue<ArtistSearchYear>(c.SelectedValue);
                return value == ArtistSearchYear.Invalid ? (ArtistSearchYear?)null : value;
            });
        parameters.ArtistEndYearAfter = year(ComboBoxArtistEndYearAfter);
        parameters.ArtistEndYearBefore = year(ComboBoxArtistEndYearBefore);
        parameters.ArtistStartYearAfter = year(ComboBoxArtistStartYearAfter);
        parameters.ArtistStartYearBefore = year(ComboBoxArtistStartYearBefore);

        if (ComboBoxRankType.SelectedValue == null)
        {
            parameters.RankType = null;
        }
        else
        {
            var value = GetDescribedObjectValue<ArtistSearchRankType>(ComboBoxRankType.SelectedValue);
            parameters.RankType = value == ArtistSearchRankType.Invalid ? (ArtistSearchRankType?)null : value;
        }

        var selectedValue = ComboBoxSort.SelectedValue;
        if (selectedValue == null)
        {
            parameters.Sort = null;
        }
        else
        {
            var value = GetDescribedObjectValue<ArtistSearchSort>(selectedValue);
            parameters.Sort = value == ArtistSearchSort.Invalid ? (ArtistSearchSort?)null : value;
        }

        parameters.Start = StringToNullableInt(GetSelectorValue<string>(ComboBoxStart));
        parameters.Results = StringToNullableInt(GetSelectorValue<string>(ComboBoxResults));

        parameters.MaxFamiliarity = SliderMaxFamiliarity.Value < 1.0d ? (double?)SliderMaxFamiliarity.Value : null;
        parameters.MinFamiliarity = SliderMinFamiliarity.Value > 0.0d ? (double?)SliderMinFamiliarity.Value : null;
        parameters.MaxHotttnesss = SliderMaxHottness.Value < 1.0d ? (double?)SliderMaxHottness.Value : null;
        parameters.MinHotttnesss = SliderMinHottness.Value > 0.0d ? (double?)SliderMinHottness.Value : null;

        if (CheckBoxFuzzyMatch.IsChecked.HasValue)
            parameters.FuzzyMatch = CheckBoxFuzzyMatch.IsChecked.Value ? (bool?)true : null;
        if (CheckBoxLimit.IsChecked.HasValue)
            parameters.Limit = CheckBoxLimit.IsChecked.Value ? (bool?)true : null;

        var buckets =
            GetSelectedItems<DescribedObject<ArtistSearchBucket>>(ListBoxBuckets)
                          .OrderBy(s => s.Description)
                          .Select(s => s.Value)
                          .ToList();
        parameters.Buckets = buckets.Count > 0 ? buckets : null;
        var genres = GetSelectedItems<string>(ListBoxGenre).OrderBy(s => s).ToList();
        parameters.Genres = genres.Count > 0 ? genres : null;
        var moods = GetSelectedItems<string>(ListBoxMood).OrderBy(s => s).ToList();
        parameters.Moods = moods.Count > 0 ? moods : null;
        var style = GetSelectedItems<string>(ListBoxStyle).OrderBy(s => s).ToList();
        parameters.Styles = style.Count > 0 ? style : null;

        parameters.ArtistLocation = string.IsNullOrEmpty(TextBoxArtistLocation.Text)
                                        ? null
                                        : TextBoxArtistLocation.Text;
        parameters.Description = string.IsNullOrEmpty(TextBoxDescription.Text)
                                     ? null
                                     : Regex.Split(TextBoxDescription.Text, @", ?")
                                            .Where(s => !string.IsNullOrWhiteSpace(s))
                                            .ToList();
        if (string.IsNullOrEmpty(TextBoxName.Text))
        {
            parameters.Name = null;
        }
        else
        {
            parameters.Name = TextBoxName.Text;
            parameters.MaxFamiliarity = null;
            parameters.MaxHotttnesss = null;
            parameters.MinFamiliarity = null;
            parameters.MinHotttnesss = null;
        }

    }

In my case nullables were vital as they allowed me to discard values when building the query.

For building the query I cheated somehow using JSON :

    protected static string GetUrlParameters(string json)
    {
        if (json == null) throw new ArgumentNullException("json");
        JsonTextReader reader = new JsonTextReader(new StringReader(json));
        string path = string.Empty;
        List<string> list = new List<string>();
        while (reader.Read())
        {
            JsonToken type = reader.TokenType;
            if (type == JsonToken.PropertyName)
            {
                path = reader.Path;
            }
            else
            {
                bool b0 = type == JsonToken.Integer;
                bool b1 = type == JsonToken.Float;
                bool b2 = type == JsonToken.String;
                bool b3 = type == JsonToken.Boolean;
                if (b0 || b1 || b2 || b3)
                {
                    var value = reader.Value.ToString();
                    if (b3) value = value.ToLower();

                    string item = string.Format("{0}={1}", path, value);
                    list.Add(item);
                }
            }
        }
        return string.Join("&", list);
    }

DescribedObject is a middle-man object that holds the desired value and the description is fetched from a value [DescriptionAttribute]

public class DescribedObject
{
    private readonly string _description;
    private readonly Object _value;

    public DescribedObject() // NOTE : for design-time
    {

    }
    protected DescribedObject(Object value, string description)
    {
        _value = value;
        _description = description;
    }

    public string Description
    {
        get { return _description; }
    }

    public Object Value
    {
        get { return _value; }
    }

    public override string ToString()
    {
        return string.Format("Value: {0}, Description: {1}", _value, _description);
    }
}

public class DescribedObject<T> : DescribedObject
{

    public DescribedObject(T value, string description)
        : base(value, description)
    {
    }
    public new T Value
    {
        get
        {
            return (T)base.Value;
        }
    }
}

A described object :

[JsonConverter(typeof(PropertyEnumConverter))]
public enum ArtistSearchYear
{
    [Description(null), JsonProperty(null)]
    Invalid = 0,
    [Description("1970"), JsonProperty("1970")]
    Year1970,
    [Description("1971"), JsonProperty("1971")]
    Year1971
}

(PropertyEnumConverter is a simple object that will convert these values according their JsonProperty attribute.)

So as you can see, I kept it stupidly simple but it took me some time as at first I had a more complex approach, again the simplicity proven really helpful though it sounds stupid sometimes.

I haven't talked about the XAML side, briefly there's absolutely nothing in it beside controls and templates, only bindings have these two properties set for them to validate. (also, the object implements INotifyPropertyChanged)

<TextBox x:Name="TextBoxArtistLocation"
            Style="{StaticResource TextBoxInError}"
            Validation.Error="TextBox_OnError"
            Text="{Binding ArtistLocation, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" />

I hope this answer will help someone, I've tried to be as concise as possible but if you have any question/comment, ask below.


问:
Regaining my spark on a project
So I'm in a little bit of a pickle. I suppose some people have gotten in my situation at some point, I know but at least as many have kept going for various reasons. To put the problem shortly; I am stuck in a project which I have after several attempts of "new fresh attitude" ended up drained out of energy and creativity and been less productive than I wish I were.

The scenario is this; I had earlier been handed a, in my opinion, half done project made in Drupal. At first it had really terrible code, but I managed to get them to clean it up a bit first. Needless to say, a poorly constructed house full of used clothes and thrash is still a poorly constructed house even without the used clothes and the thrash.

My hope currently is to regain that spark I have for all of my other projects that lets me work effeciently and mainly gets things done. In this case, I have little to none interest in working with this project. Here are some reason:

The code have quite some room for improvements. The only things that I find acceptable are the things contributed from Drupal, which are simply implemented into this project. Most custom things made in it is nothing I cherish.

I can't push myself to endure it, because I know this project will be something I'm forced to work with in the long term. In the same way I can't push myself to run the last mile of a marathon faster if I know I have to walk the entire way home afterwards.

I've read up quite a bit regarding people's opinion upon Drupal, and have came to the conclusion that Drupal is great if you have the right mindset for it. I don't have that mindset.

I prefer to create as much as possible myself and simply let a framework such as CodeIgniter worry about the process. It helps me be more confident with my code and less dependent on a module fetched from somewhere.

I generally don't believe in the project. It already takes silly long time to load, weird bugs appears from time to time that I can't even solve through google effeciently. It feels like the best thing I can do with the project is to patch it up, but I strive to do great websites, not make bad ones less bad.

Drupal has a long learning process, and I've been put in the middle of a half made project and am supposed to implemented more advanced features. Usually I have no problem to add these things in my other projects, but in Drupal it feels close to impossible often.

Apart from this, I might add that I'm currently economicly independent and don't fear loosing my job for that reason. I generally have nice colleagues but I work alone as a developer and would prefer to have at least someone whom I could discuss technical solutions with.

This project isn't something that will go away from my understanding, I've sat down with my boss, explaining how I feel regarding this project but all I get in reply is "We've spend too much time and money on this project. It needs to get completed." From my point of view, we're currently throwing money into a pit, hoping that the money will reach the surface sooner of later.

Question:

How can I regain the spark for this project? The creativity simply isn't there for me. This project won't give me much knowledge that I will have use of in the future (I have maintained lots and lots of code for 3 years) and it doesn't lead me towards my goal; to create "the perfect website".

If I can't regain the spark, what other alternatives should I consider?

Note:

I am aware that this question can seem too localized, but I think my main question can help many in a similiar position. I'm sorry if I sound like a spoiled developer who only wants to take on specific tasks, but I work so much better with project I'm comfortable with and I also like being productive.

答:
Usually, when I am facing an ugly task that I don't want to do, here is how I get past it.

If I am overwhelmed by the size of a task, then I disect the problem into smaller, more reasonable tasks that I can accomplish and focus on completing each one individually and don't think too far ahead.  Keep track of your accomplishments and you will be encouraged as you see your progress.

If there are things that could be done to make it less dreadful, make a list of them and apply them gradually (see 1).

If Drupal is the thing you dread, then there are 2 things you should do about it.

a) Face your fear: give yourself a homework assignment to learn drupal (on a smaller scale, on your terms, at home).  Once you learn it, you can make an informed decision if it is/isn't for you.  Till then, this might just be a "pain is weakness leaving the body" kind of thing.

b) Give yourself another homework assignment to build a model that demonstrates how this could be done better in another technology.  If you get it done quickly and it appears to be superior, you might get permission to implement it (because it is already done).  If not, you have gained the knowledge of two comparable technologies.

Also, there is a distinct benefit to you, if you can try to see things from your boss's point of view.  There might be more happening here than you are aware of. Suppose, for a moment, that he wasn't just making a bad decision.  How is that possible?  Under what conditions would his decision be the right thing to do?  Of course, he might actually be wrong, but I'm saying you could benefit from considering a different perspective.

ContentLicense: CC BY-SA 3.0

Title: Regaining my spark on a project


问:
Defining work days and work time
I'm working on development of SMS parking software, and I'm stuck at one point for a month... I need to implement periods of payment (or work time, of a work day, if you will). Here's the problem:

For an example, traffic wardens work from Monday to Saturday. From Monday to Friday, the work times are from 07:00 to 21:00, and on Saturday, the work time is from 07:00 to 14:00. The project request was, that the customer can pay parking by SMS unlimited, which I did, but didn't implement this logic. I started with making a table for this periods of payment, it consists of: dayofweek (INT, for use with mysql function DAYOFWEEK, to tell me which day in week is the current date), work_start and work_stop (DATETIME, for defining starting and ending the work day), but I'm unsure if I should use DATETIME, beacuse of the date, or should I use only TIME.

The idea is this:

If you send an SMS, at 20:50, Monday, it should be valid until 07:50, Tuesday (it's payed by the hour). Extending the time of payment, regarding the work time in week. Currently, it works with extending time by the hour without this rule. Really would use some help, or some ideas, I'm stuck with this for quite some time...

答:
The easiest way to take the payment periods (working hours) into account is to turn the things around and store the periods during which parking is free.

Then you can adjust the valid_from and valid_to timestamps using an algorithm like this:

```<code>if (active_payment)
    valid_from = active_payment.valid_to
else
    valid_from = now
if (valid_from in free_parking_period)
    valid_from = free_parking_period.end
valid_to = valid_from + 1 hour
if (valid_to in free_parking_period)
    valid_to = free_parking_period.end + (valid_to - free_parking_period.start)
</code>```

For storing the free parking periods, I would just go with the simplest solution of two DATETIME columns with the start and end of each period. If there is free parking on Sundays and public holidays, this will amount to approximately 300 entries for a year.

Title: Defining work days and work time

Body:
The easiest way to take the payment periods (working hours) into account is to turn the things around and store the periods during which parking is free.

Then you can adjust the valid_from and valid_to timestamps using an algorithm like this:

if (active_payment)
    valid_from = active_payment.valid_to
else
    valid_from = now
if (valid_from in free_parking_period)
    valid_from = free_parking_period.end
valid_to = valid_from + 1 hour
if (valid_to in free_parking_period)
    valid_to = free_parking_period.end + (valid_to - free_parking_period.start)

For storing the free parking periods, I would just go with the simplest solution of two DATETIME columns with the start and end of each period. If there is free parking on Sundays and public holidays, this will amount to approximately 300 entries for a year.


答:
I believe it would be much easier to have a table that stores for every hour (assuming that is your resolution) whether parking is billed (=1) or free (=0). Then iterate over the time your customer paid for by subtracting the value until his credit is used up to determine the last admissible period.

I would even suggest using two tables: the first one for the regular weekly schedule, and the second one for holidays. That way, you can easily keep track of holidays and adapt it quickly (e.g. for special events that offer free parking, etc), while being able to manage a default pattern very conveniently as well. You would need to multiply both values (a binary AND statement), then proceed as above.

Title: Defining work days and work time

Body:
I'm working on development of SMS parking software, and I'm stuck at one point for a month... I need to implement periods of payment (or work time, of a work day, if you will). Here's the problem:

For an example, traffic wardens work from Monday to Saturday. From Monday to Friday, the work times are from 07:00 to 21:00, and on Saturday, the work time is from 07:00 to 14:00. The project request was, that the customer can pay parking by SMS unlimited, which I did, but didn't implement this logic. I started with making a table for this periods of payment, it consists of: dayofweek (INT, for use with mysql function DAYOFWEEK, to tell me which day in week is the current date), work_start and work_stop (DATETIME, for defining starting and ending the work day), but I'm unsure if I should use DATETIME, beacuse of the date, or should I use only TIME.

The idea is this:

If you send an SMS, at 20:50, Monday, it should be valid until 07:50, Tuesday (it's payed by the hour). Extending the time of payment, regarding the work time in week. Currently, it works with extending time by the hour without this rule. Really would use some help, or some ideas, I'm stuck with this for quite some time...


问:
What does it mean to "expose" something?
So I am working on creating a Google App Engine Application, and I've come across the term "expose" a number of times, e.g. "your first app can expose objects using an HTTP based API" and "expose this datamodel class through a REST API". What does "expose" mean? Is there a particular action associated it, or is it an abstract part of design?</p>

答:
It means that you enable objects to be accessed through some means. In your examples, you could let the users create, read, update or delete objects (usually abbreviated to CRUD) using the HTTP protocol through some predefined way to interact with your objects (an API).

That API can adhere to a set of rules - e.g. RESTful APIs use HTTP verbs to perform some actions on objects and they adhere to some principles that say how resources should be identified/represented and how they should be manipulated through those representations.

In the context of a web application, let's say you have blog posts stored in your database. You would like the users of your application to be able to do something with those posts. They don't have to necessarily use your web site, but could perhaps use their own application that would connect to your application (e.g. a blog reader program).

As the owner of your application, you could define an interface through which your application can be accessed. For example, you might want to add an option for some users to read or write blog posts. The interface could look something like this (for an example of a more complex API, see Twitter's API definition):

If a GET /posts/{number} HTTP/1.1 is requested from your web application, you will provide a representation of your post object with an id {number} in a predefined format

Note that you are not providing an actual database object, nor your application object. You are providing a representation of your object

If a POST /posts HTTP/1.1 with a title={text1}&body={text2} is posted to your web application, you will create a new post object titled {text1} that will contain {text2} for its body, and will return an id value of the newly created post

Again, you are allowing the user the manipulate representations of your objects. The user does not have to know how your objects actually look like (that is abstracted away by the interface from the user).

Exposing the object means providing the user with an interface to access and manipulate your objects. If that interface satisfied some additional predefined conditions regarding representations of the object and states of the application that exposes its objects, then that interface is said to be a REST (or RESTful) API.


答:
"Expose" here means what it means in regular English - give access where access would not otherwise be available.

For instance "your first app can expose objects using an HTTP based API" means that someone on another machine can manipulate your object on your machine by asking for the right web pages.

Title: What does it mean to "expose" something?

Body: So I am working on creating a Google App Engine Application, and I've come across the term "expose" a number of times, e.g. "your first app can expose objects using an HTTP based API" and "expose this datamodel class through a REST API". What does "expose" mean? Is there a particular action associated it, or is it an abstract part of design?</p>


问:
Need thoughts on a course curriculum for an entry-level programmer
Would love to know your thoughts on a curriculum that will be developed for people that want to get started in the programming field. The goal of the course is to help it's students to ensure that students have an understanding of the theory and skills required to be a programmer, and have enough skills to get entry-level jobs upon graduation.

Curriculum is:

400 hours of instruction plus self-study.

40 hours of practicum

1.    Foundation

a.  Clarity

b.  Detail orientation

c.  Communication

d.  Compartmentalization/abstraction

e.  Typing

f.  Memory

2.    Theory

a.  Lexical analysis

b.  Parsing

c.  Optimization

d.  Hierarchical thinking

e.  Scope

f.  Type systems

3.    Computer Science

a.  Data structure (ex. sorting, searching, data structure transversal)

b.  Recursion

c.  Language structures (ex. arrays, linked lists, dictionaries, etc)

4.    Systems Architecture

5.    Operating System Theory

a.  POSIX

b.  IO

c.  Memory allocation

6.    Object Oriented Programming

a.  Java

b.  PL/SQL

Would love to know:

Is the above curriculum laid out clearly? If not, how would it be best to change it?

Are there any crucial components being missed from the above outline?

Should any components be removed from the above outline (considering the timeline)? Perhaps it's too detailed at certain points and is not in balance with the rest of the content?

答:
Looks like you've got some great stuff in that list. Many people might not like the theory, but I really agree that it makes you a better programmer to understand the fundamental building blocks of languages.

Here's some more items I consider to be essential for entry-level programmers to have at least some exposure:

Testing

Debugging

Web stuff (HTTP, web applications, etc.)


答:
I'd put the "Object Oriented Programming" before the "Computer Science" so that the concepts in the latter can be actually worked on something without assuming one is already knowledgeable in a programming language.

Testing is a big omission here.  Black box, white box and unit testing should be covered as part of what developers should know and understand within the broader scope of things.

The SDLC and methodologies like Agile and Waterfall would also be things I'd suggest covering early in terms of how are projects put together and how are things done in industry.  A bit of ITIL may be useful to help illustrate how some of the bigger processes like change management and incident management are handled as this may come up within industry.

Title: Need thoughts on a course curriculum for an entry-level programmer

Body:
Would love to know your thoughts on a curriculum that will be developed for people that want to get started in the programming field. The goal of the course is to help it's students to ensure that students have an understanding of the theory and skills required to be a programmer, and have enough skills to get entry-level jobs upon graduation.

Curriculum is:

400 hours of instruction plus self-study.

40 hours of practicum

1.    Foundation

a.  Clarity

b.  Detail orientation

c.  Communication

d.  Compartmentalization/abstraction

e.  Typing

f.  Memory

2.    Theory

a.  Lexical analysis

b.  Parsing

c.  Optimization

d.  Hierarchical thinking

e.  Scope

f.  Type systems

3.    Computer Science

a.  Data structure (ex. sorting, searching, data structure transversal)

b.  Recursion

c.  Language structures (ex. arrays, linked lists, dictionaries, etc)

4.    Systems Architecture

5.    Operating System Theory

a.  POSIX

b.  IO

c.  Memory allocation

6.    Object Oriented Programming

a.  Java

b.  PL/SQL

Would love to know:

Is the above curriculum laid out clearly? If not, how would it be best to change it?

Are there any crucial components being missed from the above outline?

Should any components be removed from the above outline (considering the timeline)? Perhaps it's too detailed at certain points and is not in balance with the rest of the content?


答:
I think this is a great start.

With a few changes. Your foundation section includes things like Memory management and abstraction. In my experience these are best handled by programmers who already have a bit of experience : a) writing programs and b) understanding the architecture of the machines running their programs. Furthermore, this type of instruction is best handled with lower level languages such as C or I daresay ASM. I would suggest then moving these into the actual Computer Science stage because by then certain skills will have already been obtained and you can focus more on minute and abstracted details like memory management.

The same goes for lexical analysis and presumably a bit of study on compilers and language theory. These concepts should be handled a little later on.

By the way, in terms of language usage, I think the foundations should be taught in something like python or ruby. Easy to use, dynamically typed and with a syntax and structure that generally reflects human thought. http://www.linuxjournal.com/article/3882

For the heavier stuff like POSIX, Data Structures/Algorithms I think your only serious choice is C.

Object orientation can be done in java, but nowadays I think its more forward thinking to handle it in python. Or if your really bleeding edge, maybe try Go.

I think its important to include some stuff on database theory too. Like relational languages and dependence theory.

In short, there's a few things I think you are missing, but you've got a good solid start.


问:
ado.net or EF for a point-of-sale system
We have a point-of-sale system that was developed using ado.net, our current concern is to make the application real fast in creating transactions (sales). Usually there are no performance concerns with high end PCs but with with low end PCs, the transactions take really slow.

The main concern is on saving transactions which usually calls a lot of stored procedures for inserting records within a single transaction. This usually takes time on low end PCs. We need to improve the performance since most clients will only use low end PCs to act as cashier machines. One solution we are thinking is to use entity framework for data access. The entire project is written using ado.net and development time if we shift to entity framework would be alot. Any suggestions?

答:
I would like to point out that Entity Framework (full name: ADO.NET Entity Framework) is an ORM (Object Relational Mapper) that uses ADO.NET under the hood for connecting to the database. So the question "should we use ADO.NET or EF?" doesn't really make sense in that respect. Unless you re-architect your application, adding EF to the mix is simply adding another layer on top of ADO.NET.

I sincerely doubt that ADO.NET is the source of your performance problems, however. It sounds like the problem exists in your stored procedures themselves.

I think Luc Franken's comments are on the right track, though. You need to measure and determine exactly where the delays are happening. Then concentrate on fixing exactly that problem. Anything else is groping around in the dark.


答: This is a good post. One thing that I would encoruage would be if possible, have a How to implement or think on a problem. Can give them certain scenarios and explain why would you take Approach A rather than Approach B. A few examples like these, would definitely help clear thinking and clear concepts.</p>


问:
Is it technically possible to write a JS interpreter using Lisp macro readers, in the browser?
Using macros readers, it's possible to interpret JavaScript, and have it compiled just like normal Common Lisp code. Hence getting the benefits of Lisp implementations, notably their performance. Which would mean having native performance in the browser, without cheating.

Would it be technically possible to build this for the browser? I'm mainly worried about the DOM bindings.

答:
Sorry, but your assumption is wrong.  Lisp is nice and all, but it isn't magic dynamic performance pixie dust.

Compiling/running something that looks sort of like basic JavaScript is one thing.  But it is not what is needed.

Add in what is necessary to have said JavaScript have variables that autoconvert between integer, floating point, and string representations according to the spec.  Add in the variable lookup method that JavaScript uses.  (Variables are looked up in a series of scopes, starting with the current function call.)  Add in the object model that JavaScript uses.  Continue through the spec, and you will keep on making things slower and slower.

Once you're done, even though you started with Lisp, you've simply got another implementation of a JavaScript runtime that is slow for all the reasons that any other is.  It could be faster or slower than existing implementations.  Given the optimization effort that has gone into those implementations, it likely will be slower by a wide margin.

At that point, figuring out whether to finish writing a browser in Lisp, or whether to load Lisp into a browser and apply the right JavaScript hooks is up to you.  But your performance assumptions are wrong.

Now looking at this, you could be tempted to say that it would be nice to create a new language that can be dynamic and performs better.  It would be, but there is a chicken and egg problem.  Unless all browsers have it, nobody will use it.  Unless people use it, browsers won't write it.  This is solvable, for instance look at HTML5 Canvas.  But it seems easier to solve if it is targeted at a known pain point, see HTML5 Canvas.  Ripping out all of JavaScript for something else does not seem to be an easy thing to do.  (Microsoft tried back at the dawn of the web age.  When was the last time you saw VBScript in the wild?)


答: You say you are calling a "lot of stored procedures".  If every call includes a seperate trip to the database, that is your performance issue, because trips to the database are always expensive, no matter what they do.  You should have one stored procedure to save a transaction.  If that procedure has to call other procedures, fine, as long as you don't have to make a seperate trip to the database.</p>

Title: ado.net or EF for a point-of-sale system

Body:
We have a point-of-sale system that was developed using ado.net, our current concern is to make the application real fast in creating transactions (sales). Usually there are no performance concerns with high end PCs but with with low end PCs, the transactions take really slow.

The main concern is on saving transactions which usually calls a lot of stored procedures for inserting records within a single transaction. This usually takes time on low end PCs. We need to improve the performance since most clients will only use low end PCs to act as cashier machines. One solution we are thinking is to use entity framework for data access. The entire project is written using ado.net and development time if we shift to entity framework would be alot. Any suggestions?


问:
Career advice: stay with PHP or start a new career in something else ( .Net?)
I'm planning on moving to NY in 6-12 months tops, so I'm forced to find a new job. When I'm planing to start my life in another city it's also probably a good time to think about career changes.

I've found a lot of different opinions about PHP vs .Net vs Java and this is not the topic here. I don't want to start a new fight about which language is better. Knowing a programming language is not the most important thing for being a software developer. To be a really good developer you need to know OOP, design patterns, testing... and a language is just a tool to make things happen.

So back to my question. I have mixed experience in IT - 1 year as an IT support guy (Windows administration and support), around 2 years of experience in embedded programming (VB.Net 2005) and for the last 2 years I'm working with PHP/MySQL. I have worked with Magento web shop, assisted in some projects in Symfony, modified few Drupal sites.

My main concerns are the following:

Do I continue to improve my skills in PHP e.g. to start learning some major PHP framework like Zend, Symfony maybe get some PHP certification.

Or do I start learning .NET or Java. I'm more familiar to .NET so I'll probably choose it if choice falls between .NET and Java ( or you could convince me to choose Java :).

Career-wise, I don't know what is the best choice. Learning a new framework and language is more time consuming then improving my existing skills in PHP. But with .NET you have a lot of possibilities (Windows 7 Phone development, Silverlight, WPF) and possibly bigger chances to find better jobs.

PHP jobs are less well payed then .NET, at least, according to my research (correct me if I'm wrong). But if I start now with .NET I'm just a beginner and my salary will be low. I need at least 2+ years of experience in some language to even try to find some job that is paying higher than $50-60k in NY. My main goal in the next 2-3 years is to try to find a job in the $60-80k category. Don't get me wrong, I'm not just chasing money, but money is an important factor when you're trying to start a family.

I'm 27 years old and I feel that there isn't a lot of room for wrong decisions regarding my career, so any advice will be very welcome.

Update

Thank you all for spending time to help me with my problem. All of the answers and comments have been very helpful. I have decided to stick with PHP but also to learn C# and Silverlight 4. We'll see where the life will take me.

答:
I'm 51 years old and have used at least 15 languages and/or frameworks since I got my first paying gig after graduation in 1987.

Bless you.

I never went into management because I didn't want to, but I know how to program and I know how to keep teams motivated and delivering good code. You need to work on people skills and look for interesting work that stretches you. I've never stopped learning or having fun, but there were times when I was on the road I could have done with stopping - but not coding, travelling.

As long as you can make a living and meet your personal commitments without compromising your principles, as long as you enjoy what you do (a luxury my parents' generation didn't have) just keep on keepin' on.

.Net and Java are generally corporate (because they're expensive to do useful things with, but scale really well), PHP is generally startup, I do Ruby (usually startups that came out of design studios for some reason) for lots of people as an independent. If you stick with PHP learn the OO stuff, because I think it will finally start being the way people do things, even though it is a slightly better reimplementation of what you have with Java and they could have made it much more dynamic. People who do Python and want to travel can end up doing all sorts of interesting scientific and gaming stuff all over the world. Perl is still a runner too and has a similar profile.

Forget the language, pick and industry you like, pick a company managed by human beings, and go have some fun delivering value to people who appreciate it. You won't regret it.

ContentLicense: CC BY-SA 2.5


问:
Are there strategies for discovering REST services using HATEOAS?
When building a REST service with the HATEOAS constraint, it's very easy to advertise the existence of resources through linking. You make a GET to the root of my site and I respond with the root document listing all the first-tier resources:

```<code>{
    users: { href: "/users" }
    questions { href: "/questions" }
}
</code>```

Clients which understand how to read these href values could perform GET requests on those and discover all the current resources available in the application.

This works well for basic lookup scenarios, but doesn't indicate whether a resource is queryable. For example, it may be reasonable to perform:

```<code>GET /users?surname=Smith
</code>```

Are there any formats that could express this query ability with enough information that a client could form a coherent query without needed prior knowledge of the resource?

Additionally, is there any way to express that a client is allowed to perform a POST to a given location with an expected location. For example, it could be expected that a client perform the following to create a new question resource:

```<code>POST /questions

{
    title: "Are there strategies for discovering REST services using HATEOAS?",
    body: "When building a REST service with the HATEOAS constraint, it's very..."
}
</code>```

When using HTML as the format for human consumption, we can express a lot of this through use of forms and written prompts to allow a human to discover the operations they are allowed to perform on a service.

Are there formats which are capable of similar things for clients?

答: Spring has some support for this as does resteasy.</p>


问:
Javascript Architectural Model
Are there any obvious flaws to this OO architectural model which I intend to implement using javascript? It is similar to the MVP model but instead the role of the model is broken down into three modules:

the cache (stores data instead of rerequesting from server)

the model (manages requests for raw data, retrieving it from the cache if available or the server)

the modifier (handles requests which require data which makes changes to the data on the server)

For a diagram showing how data flows through this model:

view

sets up & manages the UI possibly requiring the requesting of data from the presenter

sets up controls to alter what is displayed, possibly requiring the requesting of data from the presenter

cache

contains a record of some fetched data in data objects

has a .store() method for storing data in the cache

has a .retrieve() method for retrieving data from the cache

access for storage and retrieval is available to the model and the modifier (acting as a faster intermediate location for the sharing of information than the server)

presenter

handles requests for formatted data from view

requests data from Model (passing a callback for completion) formats data for presentation and calls view callbacks

model

handles requests for data from presenter

requests data from cache (cache.retrieve())

if data not in cache, requests it from server and then stores it in cache (cache.store())

data passed back to presenter via callbacks

modifier

handles requests from view for modifications to data

specify post, put and delete request types

only support specific types of request which may be handled separately (eg settings)

stores new data in cache (cache.store())

pushes data to the server

calls callback about the success of data storage

This is quite big project and there will be a number of others working on it so it would be good to get it right from the off.

edit 1

The cache.store() and cache.retrieve() methods both only receive the information required to refer to the data in the cache, but do not specify how it is stored. The cache methods use this information to respond with or store the correct data, but the internal structure in which the data is stored is kept secret.

答:
Alright, you're editing as you go so let's walk through what I'm currently seeing:

So a user selects something in a combo box triggering behavior to fill in the contents of another combo it's connected to.

The view requests data from the presenter with an ID(s) for the data and something identifying the combo needing to have its contents refreshed so the presenter knows who's asking so it can set up the callback to give the formatted data to the right object.

The presenter requests data from the model with the ID(s) for the data and a callback for formatting that data.

The model requests data from the cache with the ID(s) for the data. It either immediately returns data it already has or it requests data from the modifier with the ID(s) for the data. It ultimately gets that data and fires the callback with the data as an arg which ultimately formats and hands it to the widget that needed it.

The big question for me... Why are you passing the same argument 3-4 times before anything actually happens? That should smell bad to you. Very bad. Any time you pass the same arg twice in a non-currying type scenario, you should take a whiff. If two objects need to act on the same argument, they should exist as components of another object.

Why does anybody but the combo view need to know what other combo needs the formatted data? Why should anything outside of the combo view know how it's supposed to format data for the view? Why should more than one top-level object be handed the ID to ultimately get the data?

As I said earlier:

I think you're breaking out subdomains without really needing to.

Model makes sense with cache and modifier inside it. Nothing else need be bothered with the details of how those two work and that general model object is also a good place to have helpful methods for adding new types of data templates containing all the data the model components need to implement the new structure and make it accessible/bindable.

Presenter is definitely a subdomain of your view. Converting data to a view-format is one of the primary responsibilities of any view. From a portability perspective this will always need to move with whatever it is that's interacting with HTML in other ways so there's not much point in separating it.

At the highest level I tend to see these three as the evergreen concerns worthy of separating in any non-trivial UI app. There is of course plenty of other stuff you might want to separate for a given architecture. I just see these three as somewhat critical if you're talking about a highly re-usable client-side architecture/framework.

Data-structure/server-communication - Imagine you want to pull a white-label-ish make-over on another similar app of a recently acquired/merged company and you can mess with everything except for the requests that ultimately update and retrieve data from the new server whose code is a complete disaster and better left untouched for now. This is where you need a generic interface for updating, binding, and retrieving data that's decoupled from how that data is actually structured and sent to/from the server. Whatever the ajax is doing, however the data is delivered and sent and looks at point of entry, interacting with it should work the same for combo box UI app logic in the new app as it does for interacting with data in the original app. In your case, I'd probably canonicalize the new data to look like the old data at point of entry and then adapt at point of ajax interaction so you can keep using your old caching logic.

UI App Logic - This is the layer that buries the DOM and HTML stuff. A server-side dev with minimal client-side expertise should be able to figure out how to implement a widget with this. A controller basically, but I prefer implementing as another event-driven layer whose plain-english non-ui-dev-friendly DOM-agnostic events are triggered from the UI layer so we can leave it intact and just swap the HTML/canvas/svg/whatever layer out under the hood. Here we set listeners like comboObject.newChoice( handler ); so some poor bastard pinch-hitting from the server-side can handle basic implementation if needed and we have clean separation of data and environment concerns. Unless you're adding brand new types of functionality, this should never need to change once it's done and it should be relatively easy to write self-documenting code here.

UI View logic - Are we building a combo box in canvas or HTML? This is the thing we'd swap out to preserve everything else in the app for re-use in a new environment like if we wanted to make a tablet mobile app version of an existing desktop oriented site with drastically different layout but serving the same business concerns. Anything that formats data for HTML or sets events for daisy-chaining from DOM to the UI app logic layer lives in here. Nobody should see jQuery anywhere but here unless you're using it's event system for non-dom concerns. It might make sense to have a generic Presenter-like object wrapper in here that you wrap data in for convenience methods that do things like generically convert data structures to lists and tables in HTML format as well as bind data changes to behavior for the widget.

Title: Javascript Architectural Model


问:
Synchronization in the given Code
I had an interview few weeks back, and I was asked to write a code with Setters and Getters. I had written the following code;

```<code>// Just an example

Class ABC{
    private int num;

    public void setNum(int givenNum){
        this.num = givenNum;
    }

    public int getNum(){
        return num;
    }

    public ABC(){
        num = 0;
    }

    public static void main(String [] args){
        ABC object1 = new ABC();
        ABC object2 = new ABC();

        object1.setNum(5);
        System.out.println(object1.getNum());
        System.out.println(object2.getNum());
    }
</code>```

}

Now I was told, that "object1" can change the value for "object2.Num".
But I was not in agreement with this, I believe another thread which has access to object2 can change the value of object2.Num but not object1.

In the above case, I would have synchronized the setter method, or use the synchronized block inside the setter method while setting/changing the value, but I could not understand the concept of object1 changing the value of object2.Num.

I was just curious if I was missing on something. If so I would really appreciate any help regarding the same.

答:
If class ABC can be accessed from more than one thread, you will need to synchronize both setNum and getNum.  Until you leave a synch block, the new value of num need not be available to any other thread.  Until you enter a synch block, changes so made in another thread will not be visible in this one.  And in Java (but not C#), both both blocks must (according to the rules, the JLS) be synched on the same object.  (Of course, if you make the methods synchronized, they'll synch nicely on this instance of ABC.)

This might have been the point your interviewer was making.

(And making 'num' volatile (private volatile int num) would do much the same thing.)

Title: Synchronization in the given Code


问:
Python/Database Website development
I want to create my own website that would allow me to acess a database in the server and do inserts and lookups in a user friendly way. I am a seasoned user of linux and C/C++, and also have experience with Python and sqlite3, but i don't have any experience in Web development, so i have no idea where to start.

I have researched online and the best i came up with was an Apache/Nginx server together with an fcig or wscgi and Django, so that i would have database and python integration through a Django App.

Can someone tell me if this is the way to go or if there is some easier (or better) way to accomplish what i want?

答:
PHP would be easier.  Its also C-like. But it takes less of a learning curve to move into webdevelopment with because its basically designed primarily for webdevelopment. Plus they have good documentation at PHP.NET

See Is there anyone who has used Python/Ruby and PHP for a long time and still prefer PHP?

Title: Python/Database Website development


问:
ruby-idiomatic hashes vs arrays
So I am still fairly new to ruby, though I have noticed that it is very hard to create 2d-array and that hashes seem to be more of the go to data structure than arrays.

I was wondering why the Ruby community is so focused on Hashes and maybe if there is something more ruby-idiomatic than a 2d-array when trying to create something like a game board.

答:
Many times a hash can be more convenient than an array.  The use of a compound key (or hash of hashes) can be used to simulate multidimensional arrays.  This is of signficant use when the array would otherwise be a sparse array or a [jagged array].  Hashes can be easier for these cases, and they can be surprisingly common.

However, hashes aren't ordered data.  While it is very easy to put the data into a hash, it becomes more complicated to get it back out in an ordered way.  Much more complicated than just using the appropriate array in the first place.

Another factor to consider, hashes are indeed easy.  There are a number of transformations with ruby arrays that can be confusing - there are nearly twice as many methods in Array as in Hash.  Thus, if you're just tossing some data that you will want to access (and don't care about the order), especially if it is data that isn't related to each other, putting it in a hash is much easier conceptually.

Many times, hashes will stand in for a quick anonymous data object with some fields rather than making up an entirely new class for it (this is likely a better choice than metaprogramming an anonymous object with the fields to pass around).  It is easier to remember that 'userid' is in the 'userid' key rather than element 0 of the array.

Using a hash is only idiomatic when the data doesn't have an underlying, enumerable order to it already.

Title: ruby-idiomatic hashes vs arrays


问:
Should I ask/tell my boss before freelancing?
I am currently working as an intern at a consulting firm. I am soon to move to a full time employee once I graduate next semester, and I love working there. However, as a student, I lack money and I have met a business owner outside of work who has offered to hire me for some freelance web development.

Because I met this individual outside of work, I feel it would not be a conflict of interest to freelance for him. However, the work his is wanting me to do is very similar to what I already do for my current boss.

Should I speak with my boss before considering the offer?

Edit: I understand that I cannot take IP from work, and I am not in a contract, I'm employed at will.

答:
Check your contract first, but I would always advice to talk honestly with all your business relations which include your boss.

In any case, get a written approval.


问:
Text search - big data problem
I have a problem I was hoping I could get some advice on!

I have a LOT of text as input (about 20GB worth, not MASSIVE but big enough).  This is just free text, unstructured.

I have a 'category list'.  I want to process the text, and cross-reference the items in the category list, and output the categories for each match, e.g.

Input text

The quick brown fox ran over the lazy dog.

Category lookup

Colour

Red | Brown | Green

Speed

Slow | Quick | Lazy | Fast

Expected Output

Colour - Brown

Speed - Quick, Lazy

To add to the complexity of the problem, the source text probably doesn't match the categories exactly, e.g. there will have to be a fuzzy match algorithm of sorts applied here.

I want to use 'Big data' tech to solve this (whether or not it TRULY NEEDS big data isn't the question - it's a secondary objective).

My thoughts are to utilize Hadoop Map/Reduce with Lucene to do the fuzzy-matching.

What do you think?  Am I way off base?

Thanks a lot - ANY advice appreciated!!

Duncan

答:
It sounds like the biggest problem you have left is to actually develop the categories and flesh them out.

Given a set of categories, and a set of 'marker' words for each category. (You'll want to read about stemming (turn vegetables -> vegetable) and stopping (skip common, meaningless words the, etc). A good implementation of the stemmer you can find will be either the Porter2, or Krovetz, but this is language-dependent.

Ultimately, this depends upon having categories - in Machine Learning, these are labels, and a set of features that you use to turn the data into inputs to a function that returns labels. In a way, it sounds like you want your features to be membership in a particular set, and your labels will correspond 1:1 with features, and you're allowing for multiple labels on each.

That being said, streaming through 20GB of data, particularly if you partition it on a rather common 4 core machine will go quickly. I'd recommend you take a chunk of 100 or so sentences, and build up your training and test data. Then move it to Hadoop, if you're interested. When data gets big, make sure your experiments start tiny.

map: (sentence, sentence_id) -> (category, sentence_id)

reduce: (sentence_id, '(category, category, ...))

Title: Text search - big data problem


问:
Question about Java nested classes design decision
I was shocked today to discover that this code compiles cleanly in Java:

```<code>public class A {
  public static class B {
     private static void x() {}
  }
  private static class C {
     private /* So, private to what exactly? */ static void x() {}
  }
  public static void main(String[] args) {
    B.x(); C.x();
  }
}
</code>```

It seems Java's private keyword indicates only top-level-class-privacy; which, given the general convention to name Java source files by class, means that Java effectively provides only file-level private visibility, not true private visibility.  (The equivalent code in C++ does not compile with a visibility error.)

Would anyone be able to explain why Java was designed this way?  Or is this just Java's way of telling everyone not to use nested classes?  (It certainly hacks in an implementation of a two-way C++ friend relationship, but we already have package-level visibility for that; this seems to make the one-way equivalent impossible.  Moreover, it necessitates the compiler creating more hidden accessor methods to circumvent the visibility, and under-the-hood downgrading of nested class visibility control to make all this not error out at runtime.  Really, why the trouble?)

答:
Welcome to Java.

Your code is in the file for class A.  The word "private" in this file means private to class A.  Class B is just a part of class A.  However, the "private" for method x does serve an important purpose; it means that no code outside of class A can call that method on an instance of class B.  This means that while an instance of class B could be available all across the program, any problems caused by method x must be caused somewhere in class A.  In a large, complex system this encapsulation makes life a lot easier, both for debugging and for modifying code.

The idea here is that an object of class A can communicate with the rest of the system with instances of classes like B and C while keeping a great deal of control over those instances--since method x can only be called from within A.  (And if the classes were not static, A would have even more ways to control B and C.)

In Java and C#, nested classes are completely different things with completely different purposes; do not confuse them.  In C#, they're just normal classes with slightly limited scope.  In Java, nested classes are very much the agents, or extensions, or representives, of their top-level ancestor.  The Java approach won't make too much sense until you work with it a while on a complex system, but if you do, it will become very addictive.


问:
Is there a tool or process to help FOSS authors agree on a license?
The Evercookie project has several contributors and there is no explicit license for the code.  There is currently discussion on the dev mailing list trying to figure out what the licensing options are.

Is there any tool or process that can be used to find consensus among the various licenses?

What can be done if some contributors are non-responsive, can't be found, etc?

答:
If there aren't too many contributors, you could just create a spreadsheet with all their emails and chart in their responses as you get them back.

The benefit of this is that the only thing the contributors have to do is reply to an email with essentially just a "yes" or a "no", which is so simple that there's no reason to put it off.

Another option may be to look into survey websites, I'm sure there's one out there that lets you email unique links to a survey that doesn't require a login and track the responses. You could look into your options there.

If people have different opinions on what license should be used, the best way to get people to agree on a single one is to ask people if they would be okay with the code being licensed under a specified license (and provide reasons for that license over others), as opposed to asking them which license they would like.

As for non-responsive people, there isn't a whole lot you can do outside of trying to get a hold of them. As Bart's comment states, since your project currently has no license, I believe (IANAL) that no one can redistribute it without getting permission from all the copyright holders first. Additionally, you might have an issue with people who are going to be very stubborn about what license they want. The only thing you can do is try to negotiate. I'd like to think that people who contribute to open source software are going to be fairly relaxed about this kind of stuff, but you never know... some people have very strong opinions on software licenses.


答:
I have to agree with Joel. But his answer goes beyond technical skills and preferences.

In my experience it's usualy your job requirements that point you towards a specific technology or programming language, not what you would like to use; unless its a startup that has not defined what they are going to use yet. And no one can guarantee that you will find a job/company utilising exactly what you are looking for.

So the real question is: are you good in learing new stuff? can you address a problem and solve it in a timely manner regardless programming language?

A good programmer should be well aware of software construction and software engineering concepts. Your question makes me believe that you haven't invested enough time towards learning those, which probably makes you uncertain of your skills and what your actual potentials are. And honestly, if you haven't done that its about time you do, because without those you will probably not go far.

There is another thing that most of us programmers tend not to give any attention to before we get older than 30: Programming skills is only half of the skills that make a good programmer. Are you a good team player? Are you willing to pass knowledge to coworkers as willingly as you are (or should be) receiving knowledge from others? People skills are higlhy underestimated by many of us, while they are actually very important.

Title: Career advice: stay with PHP or start a new career in something else ( .Net?)

Body:
I'm planning on moving to NY in 6-12 months tops, so I'm forced to find a new job. When I'm planing to start my life in another city it's also probably a good time to think about career changes.

I've found a lot of different opinions about PHP vs .Net vs Java and this is not the topic here. I don't want to start a new fight about which language is better. Knowing a programming language is not the most important thing for being a software developer. To be a really good developer you need to know OOP, design patterns, testing... and a language is just a tool to make things happen.

So back to my question. I have mixed experience in IT - 1 year as an IT support guy (Windows administration and support), around 2 years of experience in embedded programming (VB.Net 2005) and for the last 2 years I'm working with PHP/MySQL. I have worked with Magento web shop, assisted in some projects in Symfony, modified few Drupal sites.

My main concerns are the following:

Do I continue to improve my skills in PHP e.g. to start learning some major PHP framework like Zend, Symfony maybe get some PHP certification.

Or do I start learning .NET or Java. I'm more familiar to .NET so I'll probably choose it if choice falls between .NET and Java ( or you could convince me to choose Java :).

Career-wise, I don't know what is the best choice. Learning a new framework and language is more time consuming then improving my existing skills in PHP. But with .NET you have a lot of possibilities (Windows 7 Phone development, Silverlight, WPF) and possibly bigger chances to find better jobs.

PHP jobs are less well payed then .NET, at least, according to my research (correct me if I'm wrong). But if I start now with .NET I'm just a beginner and my salary will be low. I need at least 2+ years of experience in some language to even try to find some job that is paying higher than $50-60k in NY. My main goal in the next 2-3 years is to try to find a job in the $60-80k category. Don't get me wrong, I'm not just chasing money, but money is an important factor when you're trying to start a family.

I'm 27 years old and I feel that there isn't a lot of room for wrong decisions regarding my career, so any advice will be very welcome.

Update

Thank you all for spending time to help me with my problem. All of the answers and comments have been very helpful. I have decided to stick with PHP but also to learn C# and Silverlight 4. We'll see where the life will take me.


答:
Have you looked at the ACM Curriculum Recommendations?

ACM. the Association for Computing Machinery, is the professional society for computer software people.  They've been thinking about what needed to be taught, in what order, with what emphasis, for decades.


问:
Structuring Access Control In Hierarchical Object Graph
I have a Folder entity that can be Moderated by users.  Folders can contain other folders.  So I may have a structure like this:

```<code>Folder 1
    Folder 2
        Folder 3
    Folder 4
</code>```

I have to decide how to implement Moderation for this entity.  I've come up with two options:

Option 1

When the user is given moderation privileges to Folder 1, define a moderator relationship between Folder 1 and User 1.  No other relationships are added to the db.

To determine if the user can moderate Folder 3, I check and see if User 1 is the moderator of any parent folders.

This seems to alleviate some of the complexity of handling updates / moved entities / additions under Folder 1 after the relationship has been defined, and reverting the relationship means I only have to deal with one entity.

Option 2

When the user is given moderation privileges to Folder 1, define a new relationship between User 1 and Folder 1, and all child entities down to the grandest of grandchildren when the relationship is created, and if it's ever removed, iterate back down the graph to remove the relationship.  If I add something under Folder 2 after this relationship has been made, I just copy all Moderators into the new Entity.

But when I need to show only the top-level Folders that a user is Moderating, I need to query all folders that have a parent folder that the user does not moderate, as opposed to option 1, where I just query any items that the user is moderating.

Thoughts

I think it comes down to determining if users will be querying for all parent items more than they'll be querying child items... if so, then option 1 seems better.  But I'm not sure.

Is either approach better than the other?  Why?  Or is there another approach that's better than both?  I'm using Entity Framework in case it matters.

答:
Option 1 is the easiest and cleanest and minimal solution.  You are right that there's less work involved in updating permissions when you move folders and there's less work involved in working out where a user's moderation permissions were actually set.  So I would seek to implement this method.  If you start adding additional records beyond what the super-admin originally entered (as per option 2), you start adding noise to your model and then you've got to filter the actual information back out again.

If you're storing your data in a database, you should look up the Nested Set Model.  In this model, you add a 'left' and 'right' field to your folders table, and give those fields values such that a folder's left and right values encompass the left and right values of all descendant folders (there is a diagram on the wikipedia page that nicely demonstrates this).  This model makes it very simple to identify all the children, grandchildren, etc. of a folder and all the parents of a folder - something that can be quite complex with just a standard parent id link.


问:
Refactor working code for reuse or duplicate?
I have always avoided duplicating code regardless of the circumstance.  For example, if I have a working piece of functionality that needs to be re-used by different entities, I always refactor to make this functionality available.  Under no circumstance would I duplicate code.  I am probably a little rigid when it comes to this but I really do not like duplicating code.

I currently had a slight disagreement with our Team Lead who suggested that instead of refactoring, I should copy entire piece of functionality I require into a different class and then we can decide how best to refactor at a later date. This is even after confirming  that my previous refactoring efforts did not break any of the unit tests.

I further had this conversation today with my previous manager, and his mentor, who both sided with my Team Lead.  Their argument is incurring technical debt is OK, and almost always preferable, especially if you are running into time constraints, which I understand.  My counter argument was yes, we do not want to skip deadlines but one must always consider the cost of refactoring and this usually should be the first instinct, especially if we are simply moving functionality into a new location that renders it accessible to all.  Proper unit test can also ensure that refactoring efforts do not break existing functionality.  Also is it not always better to pay off the debt now rather than later?  I can only imagine what this task will entail if all members of the team simply duplicated code.

Suffices to say that we had to agree to disagree.  In his book titled Clean Code, Robert Martins emphasis continuous refactor during development so I was surprised by the response of my previous manager.

What are you opinions on this?

答:
If your team lead, previous manager and mentor are all saying that you don't have the time to refactor now because of time constraints, then you don't have time to refactor it now. Note it, stick a TODO in there and refactor it later.

You're not being held responsible for the delivery date. They are. You're probably not aware of what's going on with the bigger picture, and you don't need to explain to the CEO/board why the project is two weeks late. Saying "We wanted to have a cleaner code base now, instead of in a months time, so we're delaying the project, and now your job is on the line" is not a good excuse.

In an ideal world you would always be able to refactor and not incur technical debt. It's always the preferred solution, no-one is arguing that. I too hate duplicate code - I'm actually in the situation now where I've inherited a lot of copy and paste code and it's going to be a nightmare to fix up, but the business did what they needed to do to deliver the project, and they can now afford to spend the extra time to clean up the code.


问:
application logic, business logic, models, controllers - where to put the application's brains?
I'm trying to wrap my head around models, views, and controllers, but I feel as though the more I read, the more conflicting information I seem to encounter. I guess the general goal is--as far as I've seen--to shoot for fat models and thin controllers, but I'm still a bit baffled by where to put what. Can I give an example from something I'm working on?

This is just a personal project that I'm messing about with in PHP for fun--a mini-game of sorts. Adding timed tasks to an itinerary and collecting rewards when the task completes. So a class kind of like this exists:

```<code>class ItineraryEntry {
    public $user_id;
    public $task_id;
    public $completion_time;
}
</code>```

And another class like this:

```<code>class Task {
    public $task_id;
    public $description;
    public $duration; //in seconds
}
</code>```

So in the user interface, the user sees a task description and clicks something like "Add to Itinerary". Now if I'm understanding correctly, the controller needs to pick up that request and do something with it. But...how much? So for example, I need to figure out when the task will complete. Keeping it simple, that's merely time() + the duration of the task. So does the controller do that calculation and then give it to the model to validate, or does the model just handle all of it? And the controller is really just a glorified router of data?

Then the second part is what happens when an itinerary task completes. So from the user interface, a task will show as completed if the completion time is in the past, and the user will have to click something like, "Claim Rewards". Let's just say it's...I don't know...XP (i.e., experience points)--something that gets updated on the user's account. And let's say that the amount of XP is calculated in some way based upon the difficulty of the task, time required, etc.

So where would I put that calculation? Is that inside the model class for my user object, or do I have a controller that figures all of that out and then sends it to the user object? In the model for my itinerary entry model? And the reason I ask this specifically is because any kind of Claim Rewards code would have to do a couple of things at least:

Actually claim the reward and update the user's account

Clean up the expired task from the database (or marking it completed or something)

So it would be interacting both with the user and the itinerary entry.

A little specific guidance would be really helpful. My brain is starting to hurt from reading all of these explanations that are kind of like what I need to know, but not totally. So thanks in advance!

答:
With whatever model works for you. MVC is a pre-web concept that's not really a perfect fit for a scenario where you have that big giant http wall to chuck stuff over. It's also a heavily loaded marketing term that carries more "serious-sound" weight than practical use to most.

I think of the controller's role as being app logic and I think older-school versions of MVC agree with that.

I think of model as biz logic.

The DB (in my mind) should be separate. Log-in details are really an app-logic concern that interacts with the DB, just as whether or not that user gets a 25% discount is a business logic concern but is also tied to the DB.

The user of the server-side is the browser. Not the guy in front of the computer. Web apps are basically best thought of as two apps. Your job on the server-side is to present something the browser can use.

Am I right by a lot of MVC definitions? Probably not but I'm considering the application in terms of ways I might want to break all but one piece of it out. The DB might work differently but I could keep everything else. The client-side might need different HTML but I keep everything else. I might want the same DB, biz logic, and HTML but app logic details like how users are authenticated and how we need the HTML built/templated might change a bunch.

When you have control, split things out as they're important to be split out to you. People advocating the "one way" to do MVC aren't doing it the way it was originally conceived so don't fret about whether you're doing it right. Just figure out what's right for you.


问:
How can degree of order in a list be measured?
The following questions gave me food for thought:

Efficient way to shuffle objects

I'd like to write an "ultimate shuffle" algorithm to sort my mp3 collection

When you sort a list - you always have a base-line(numbers, alphabet, ...) which tell you how to order the list.

Question: When you shuffle a set - how would you measure "degree of order"?

For example: 9 8 7 6 5 4 3 2 1 is ordered, even if completely differently than 1 2 3 4 5 6 7 8 9.  And 9 8 7 6 1 2 3 4 5 also has some order (if you look at it in chunks: 9 8 7 6 and 1 2 3 4 5). Another example could be 9 2 3 4 5 6 7 8 1.
How can you determine if one listing is less or more ordered than another.

Note: since there has been some confusion about the goal of this question - I would like to specify, that I'm not looking for a method to measure randomness. 1234 is just a random set of 4 digits as 4213, but it seems to me that 1234 is more ordered than 4213. The comment about "Kolmogorov complexity" by user61852, or the answer by Mathew Foscarini which mentions measuring the deviation between neighboring numbers in a sequence, are the types of answers I am looking for. I'm not sure if the measure entropy approach in the comment by MichaelT helps identify order in a list - if the comments could be elaborated into answers that would be great.

答:
Ordered means lack of deviance in progression, by repeating or incremental deviances.   Like counting by ones, counting by two's, etc. However, arranging random numbers from smallest to largest is definately ordering them, unless it's hidden within a larger group of numbers.

An incremental deviance is also ordered, but not as much, such as 1,(+1) 2, (+2) 5.

2 4 6 8 is more ordered than 1 2 5 8  Even though the average deviance is smaller in the second number.

The key is the deviances of the deviances (of the deviances).  So if you can measure that, determining whether there's a progression, or a pattern that repeats (or progresses), you should be able to compare one set of numbers to any other to determine if one is more ordered than the other as a factorable test.


答:
Your manager is about to sacrifice code-maintainability because the project is running out of time. In the short term it is much faster to duplicate code ("copy&paste inheritence") and add a "to do" than to refactor now.

From my experience you will never have the time to do the refactoring later :-(.

You can give management a time estimate how much extra time is required to do the refactoring and if they still say no you have to do what they want.

If you write a short email that summaries the political management decision so you are protected from a possible later blaming-game because of "the bad code quality with so many code duplicates".

Title: Refactor working code for reuse or duplicate?

Body:
I have always avoided duplicating code regardless of the circumstance.  For example, if I have a working piece of functionality that needs to be re-used by different entities, I always refactor to make this functionality available.  Under no circumstance would I duplicate code.  I am probably a little rigid when it comes to this but I really do not like duplicating code.

I currently had a slight disagreement with our Team Lead who suggested that instead of refactoring, I should copy entire piece of functionality I require into a different class and then we can decide how best to refactor at a later date. This is even after confirming  that my previous refactoring efforts did not break any of the unit tests.

I further had this conversation today with my previous manager, and his mentor, who both sided with my Team Lead.  Their argument is incurring technical debt is OK, and almost always preferable, especially if you are running into time constraints, which I understand.  My counter argument was yes, we do not want to skip deadlines but one must always consider the cost of refactoring and this usually should be the first instinct, especially if we are simply moving functionality into a new location that renders it accessible to all.  Proper unit test can also ensure that refactoring efforts do not break existing functionality.  Also is it not always better to pay off the debt now rather than later?  I can only imagine what this task will entail if all members of the team simply duplicated code.

Suffices to say that we had to agree to disagree.  In his book titled Clean Code, Robert Martins emphasis continuous refactor during development so I was surprised by the response of my previous manager.

What are you opinions on this?