Когда объединять общий функционал?- Публичный статический объект с инициализацией - PullRequest
1 голос
/ 06 января 2012

Это обычный случай, когда я кодирую ... Я вижу некоторый код, который выглядит примерно так ... и я знаю, что явно нехорошо иметь избыточную функциональность в моем коде.

Однако,это абсолют?0 Избыточность?У меня есть две функции ниже, которые похожи друг на друга.ViewH.bookmark и ViewH.tweet.

Я пытаюсь решить, следует ли мне извлекать общую функциональность в функцию с именем ViewH.mark ().

EDIT

var ViewH = {
    MARK: 
    {
        FIELD:      '|',
        ROW:        '||',
        PASS:       '<xx_p>',
        FAIL:       '<xx_f>'
    },
    return_string:  '',
    mark: function(passed_function, embeddedAml)
    {
        var return_string,
            first_split, 
            element_count, 
            second_split;

        return_string = '';
        first_split = embeddedAml.split( ViewH.MARK.ROW );
        for( element_count=0; element_count < first_split.length; element_count++)
        {
            second_split = first_split[element_count].split( ViewH.MARK.FIELD );
            passed_function(second_split);
        }
        return ViewH.return_string;
    },
    bookmark: function ( embeddedAml ) 
    {
        ViewH.return_string='';
        return ViewH.mark(ViewH.bookmark_inner, embeddedAml);
    },
    tweet: function ( embeddedAml ) 
    {
        ViewH.return_string='';
        return ViewH.mark(ViewH.tweet_inner, embeddedAml);
    },
    portfolio: function ( embeddedAml ) 
    {
        ViewH.return_string='';
        return ViewH.mark(ViewH.portfolio_inner, embeddedAml);
    },
    bookmark_inner: function ( second_split )
    {
        ViewH.return_string = ViewH.return_string 
        + '<img name="bo_im" class="c" src="'
        + 'http://www.google.com/s2/favicons?domain=' 
        + second_split[0] 
        + '" onerror="Arc.BookmarkError(this)"><a target="_blank" name="bookmark_link" class="b" href = "' 
        + second_split[1] 
        + '">' 
        + second_split[2] 
        + '</a>';
    },
    tweet_inner: function ( second_split )
    {
        ViewH.return_string = ViewH.return_string 
        + '<div class="Bb2b"><img class="a" src="' 
        + Constant.PICTURES + second_split[ 0 ] 
        + '.jpg" alt=""/><a class="a" href="javascript:void(0)\">' 
        + second_split[ 1 ]  
        + ' posted ' 
        + ViewH.pretty( second_split[ 2 ],second_split[ 3 ] ) 
        + '</a><br/><p class="c">' 
        + second_split[ 4 ] 
        + '</p></div>';
    },
    portfolio_inner: function ( second_split )
    {
        if( ( second_split[ 1 ] === 'docx' ) || ( second_split[ 1 ] === 'xlsx' ) )
        {   
            ViewH.return_string = ViewH.return_string 
            + '<img name="bo_im" class="c" src="' 
            + Constant.IMAGES + second_split[1] 
            + '.ico"><a target="_blank" name="bookmark_link" class="b" href = "/' 
            + Constant.ROOT 
            + second_split[1] 
            + '/' 
            + second_split[0] 
            + '.' 
            + second_split[1] 
            + '">' 
            + second_split[0] 
            + '.' 
            + second_split[1] 
            + '</a>';
        }
        else
        {
            ViewH.return_string=ViewH.return_string 
            + '<simg name="bo_im" class="c" src="' 
            + Constant.IMAGES 
            + 'generic' 
            + '.ico"><a target="_blank" name="bookmark_link" class="b" href = "' 
            + Constant.TEXT 
            + second_split[0] 
            + '.txt">' 
            + second_split[0] 
            + '.' 
            + second_split[1] 
            + '</a>';
        }
    },

Ответы [ 3 ]

3 голосов
/ 06 января 2012

Как правило, да.

Одним из решающих факторов является совпадение кода по совпадению или выполнение аналогичной задачи.Если последнее верно, должны ли вы изменить функциональность одного в будущем (особенно ту часть функциональности, которая является общей), захотите ли вы также изменить функциональность другого?Если это так, это облегчает ваше решение - объедините код там, где вы можете.

Даже если код совпадает по совпадению, возможно, все же имеет смысл создать универсальную библиотечную функцию, которая очищает ваш код.

3 голосов
/ 06 января 2012

Это отличный вопрос, но нет ответа, который применим ко всем случаям.Это будет зависеть от того, как выглядит ваш код.Как правило, следует избегать избыточности, но иногда хуже чрезмерно спроектировать ваш код и попытаться поместить его в блок, в который он на самом деле не вписывается.

В вашем случае вы определенно могли бы извлечь выгоду из общихкод и потянув его в общий метод.Похоже, что единственное различие между вашими методами заключается в части рендеринга, и было бы просто передать функцию рендеринга в ваш метод "mark".

Ваш метод "mark" будет выглядеть примерно так:

mark: function(embeddedAml, renderer) {
    var return_string,
        first_split, 
        element_count, 
        second_split;

    return_string = '';
    first_split = embeddedAml.split( ViewH.MARK.ROW );

    for( element_count=0; element_count < first_split.length; element_count++)
    {
        second_split = first_split[element_count].split( ViewH.MARK.FIELD );
        return_string = return_string + renderer(second_split);
    }

    return return_string;
}

Вы бы сохранили методы закладок и твитов, но они также изменились бы:

bookmark: function (embeddedAml) {
    return this.mark(embeddedAml, function(data) {
        return '<img name="bo_im" class="c" src="' + 
        'http://www.google.com/s2/favicons?domain=' +
        data[0] + 
        '" onerror="Arc.BookmarkError(this)"><a target="_blank" name="bookmark_link" class="b" href = "' +
        data[1] + '">' + 
        data[2] + '</a>'
    });
}

Теперь ваш код рендеринга (единственный код, который отличался) контролируется независимо, но кодэто перекрытие находится в общем месте, и если оно меняется, вам нужно обновить его только в одном месте.

2 голосов
/ 06 января 2012

Я бы определенно попытался объединить их.Вы заметите, что тело цикла for - единственное, что отличается между ними.Вот один из подходов (большинство ViewH исключено):

var ViewH = {
    bookmark: function(embeddedAml) {
        return ViewH.combinedFunc(embeddedAml, function(parts) {
            return '<img name="bo_im" class="c" src="' + 
                   'http://www.google.com/s2/favicons?domain=' +
                   parts[0] + 
                   '" onerror="Arc.BookmarkError(this)"><a target="_blank" name="bookmark_link" class="b" href = "' +
                   parts[1] + '">' + 
                   parts[2] + '</a>';
        });
    },

    combinedFunc: function (embeddedAml, handler) {
        var return_string,
            first_split, 
            element_count, 
            second_split;

        return_string = '';
        first_split = embeddedAml.split(ViewH.MARK.ROW);

        for(element_count=0; element_count < first_split.length; element_count++) {
            second_split = first_split[element_count].split(ViewH.MARK.FIELD);
            return_string = return_string + handler(second_split);
        }

        return return_string;
    },
}

Вы можете легко сделать то же самое для tweet.Очевидно, что вы захотите назвать функцию как-нибудь лучше, чем combinedFunc, но вам нужно будет выбрать это имя в зависимости от контекста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...