Как бы я рефакторинг этого кода, чтобы быть более объектно-ориентированным? - PullRequest
2 голосов
/ 08 марта 2011

UPDATE

Поэтому я последовал совету ' justkt ' и ' xtofl ' и внес в свой код некоторые огромные изменения. Я думаю, что это лучший дизайн, но, пожалуйста, оставляйте отзывы и предложения по улучшению.

Во-первых, я создал несколько перечислений ...

var SymbolName = {
    alpha : 0,
    beta : 1,
    // ... etc...
};
Object.freeze(SymbolName);

var TypeOfSymbol = {
    GreekSymbol : 0,
    // ... etc...
};
Object.freeze(TypeOfSymbol);

... затем я реорганизовал свой класс Symbol, убрав все переменные-члены, которые у меня были ранее, и превратив его в объект, который запоминает 4 значения на Symbol ...

function Symbol(name, id, value, type) {

    var name = name;
    var id = id;
    var value = value;
    var type = type;

    this.getName = function() {
        return name;
    };

    this.getID = function() {

        return id;
    };

    this.getValue = function() {

        return value;
    };

    this.getMathMLTag = function() {

        var tag;
        switch (Number(type)) {

            case TypeOfSymbol.GreekSymbol:

                tag = 'mi';
                break;

            default:

                tag = 'mo';
                break;
        }
        return tag; 
    };
};

Теперь, чтобы создать и получить доступ к этим Symbol объектам, я создал Symbols объект, который имеет массив всех возможных Symbol объектов ...

function Symbols() {

    var theSymbols = new Array();

    // new Symbol(name, id, value, type)
    theSymbols[SymbolName.alpha] = new Symbol('alpha', 'symbol_' + SymbolName.alpha, 'α', TypeOfSymbol.GreekSymbol);
    // ... etc...

    this.getSymbol = function(symbolID) {

        return theSymbols[symbolID];
    };
};

Так что теперь все просто. Я объявляю переменную var symbols = new Symbols(); и, если я хочу получить символы, я могу просто сделать:

symbols.getSymbol(SymbolName.alpha); // get the Symbol object
symbols.getSymbol(SymbolName.alpha).getValue(); // get the Symbol value
symbols.getSymbol(SymbolName.alpha).getID(); // get the Symbol ID

Это позволяет мне легко создавать <div> s для каждого Symbol:

$.fn.AppendGreekSymbols = function() {
    var symbol;
    var mathTag;
    var openingTags;
    var closingTags;

    // lower-case Greek Alphabet
    var index = SymbolRanges.GreekSymbolsStartIndex;

    for (index; index <= SymbolRanges.GreekSymbolsEndIndex; index++) {

        symbol = symbols.getSymbol(index);

        openingTags = '<div id=\"' + symbol.getID() + '\" class=\"symbol ' + symbol.getName() + '\">';
        mathTag = '<math display=\"block\"><' + symbol.getMathMLTag() + '>';
        closingTags = '</' + symbol.getMathMLTag() + '></math></div>';

        $('.greek-symbols').append(openingTags + mathTag + symbol.getValue() + closingTags);
    }
};

Кроме того, я могу легко определить обработчик 1 клика для всех Symbol объектов:

$(function() {

    $('div.symbol').click(function() {

        var targetSymbolID = $(this).attr('id').split('_')[1];
        var symbol = symbols.getSymbol(targetSymbolID);
        $().InsertSymbol(symbol);
    });
});

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

Оригинальный пост

У меня есть Symbol класс, который выглядит примерно так:

function Symbol() {
    // I need to define some functions in here  
};
Symbol.prototype.alpha = "&#x03B1;";
Symbol.prototype.Alpha = "A";
Symbol.prototype.beta = "&#x03B2;";
Symbol.prototype.Beta = "B";
Symbol.prototype.gamma = "&#x03B3;";
Symbol.prototype.Gamma = "&#x0393;";
Symbol.prototype.delta = "&#x03B4;";
Symbol.prototype.Delta = "&#x0394;";
... and so on for nearly 500 symbols...

Каждый символ будет по отдельности помещен в свой собственный элемент <div class="symbol alpha">, но alpha будет именем класса, соответствующим имени символа ... поэтому существуют и другие подобные элементы, такие как <div class="symbol beta">, <div class="symbol gamma"> и т. д. Итак, для этого у меня было бы много повторяющегося кода:

var symbol = new Symbol();
$('.greek-symbols').append('<div class="symbol alpha">' + symbol.alpha + '</div>');
$('.greek-symbols').append('<div class="symbol beta">' + symbol.beta + '</div>');
$('.greek-symbols').append('<div class="symbol gamma">' + symbol.gamma + '</div>');
... etc...

Теперь я хочу настроить обработчик события щелчка для каждого символа и соответствующего контейнера <div>. Опять же, у меня было бы много повторяющегося кода, например:

$('div.symbol.alpha').click(function() {

    $().InsertSymbol(symbol.alpha);
});
$('div.symbol.beta').click(function() {

    $().InsertSymbol(symbol.beta);
});
... and so on...

Я думаю, что есть лучший способ сделать это. В идеале мне бы хотелось иметь только один обработчик событий, который бы анализировал имя символа из класса, просматривал его в классе Symbol и работал бы таким образом. Итак ...

$('div.symbol').click(function() {

    // I know the following code doesn't correctly parse out the correct class,
    // I'll worry about that later, but the idea is clear
    var symbolName = $(this).attr('class'); // parse out the correct class, the symbol name
    $().InsertSymbol(Symbol.getSymbol(symbolName));
});

... а в классе Symbol у меня будет эта getSymbol() функция, которая будет принимать имя, искать символ и возвращать правильный. Однако я не уверен, как это сделать в JavaScript / jQuery. Как бы я настроить эту логику? Я не знаю, есть ли в JavaScript класс HashMap, такой же, как в Java, так что будет хорошим способом поиска этих символов?

Дайте мне знать, если мне нужно уточнить.

p.s. Я приветствую любые предложения относительно источников / ссылок для хорошего объектно-ориентированного дизайна

Ответы [ 5 ]

3 голосов
/ 08 марта 2011

Javascript имеет то, что иногда называют ассоциативными массивами , но чаще всего в Javascript объектные литералы .Ниже литерала «values» объекта хранятся ваши ключи (имена классов) и значения (символы).

function Symbol() {
    // I need to define some functions in here  
};
Symbol.prototype.values = {
    alpha: "&#x03B1;",
    beta: "&#x03B2;",
    gamma: "&#x03B3;",
    // ...and so on

}; 

Или вы можете сделать это следующим образом:

function Symbol() {
    // I need to define some functions in here  
};
Symbol["alpha"] = "&#x03B1;";
Symbol["beta"] = "&#x03B2;";
Symbol["gamma"] = "&#x03B3;";
// ...and so on

Вместо того, чтобы иметь ваши divиметь класс «символа SYMBOLNAME», такого как «символ альфа», я бы предложил иметь класс символа и идентификатор SYMBOLNAME, такой как альфа.Конечно, это работает, только если ваши символы уникальны для страницы.Учитывая это, вот как вы должны получить значение:

$('div.symbol').click(function() {
    var symbolName = this.id; // get the symbol name from the ID
    $().InsertSymbol(Symbol.values[symbolName]);
    // or in case of the second option, $().InsertSymbol(Symbol.[symbolName]);
});
3 голосов
/ 08 марта 2011

Вы можете извлечь выгоду из объектно-ориентированного подхода: если вы определите класс Symbol, у него, вероятно, будет много экземпляров , а не переменных-членов .

Примечание: код еще не проверен - возьмите идею.

РЕДАКТИРОВАТЬ: jsfiddle на http://jsfiddle.net/xtofl/ttjZw/4/

// the class:
function Symbol( name, lowname, upcase, lowcase ) {
   this.name = name;
   this.lowname = lowname;
   this.upcase=upcase;
   this.lowcase=lowcase;
}
// creates a div - may be done using jQuery DOM functions
Symbol.prototype.makedivs = function() {
   return "<div class='"+this->name+"'>"+this.upcase+"</div>"
         +"<div class='"+this->lowname+"'>"+this.lowcase+"</div>"
}
Symbol.prototype.addhandler = function() {
   var symbol = this;
   $(this->name).click()( function(e){ document.write( symbol->upcase ); } );
}



$(document).ready( function() {

  // the instances:
  var symbols = [
    new Symbol( 'alfa', 'Alfa', "&#x03B1;", "&#x03B1;" ),
    new Symbol( 'beta', 'Beta', "&#x03B1;", "&#x03B1;" ),
    //...
  ];
  for( var i = 0; i != symbols.length; ++i ) {
    symbols[i].addhandler();  
  }

});
2 голосов
/ 08 марта 2011
$.fn.page = function() {
  window.page = this;

  this.symbols = {
    'alpha': ['A',"&#x03B1;"],
    //etc
  }

  this.delegate('div.symbol', 'click', function(event) {
    var div = $(event.target),
        // parse symbol name from class
        symbolClass = $(this).attr('class').replace('symbol',''),
        // fetch map 
        map = page.symbols[symbolClass],
        // replace text
        newText = div.text().replace(map[0],map[1]);
    div.text(newText);    
  });

};

$(document).ready(function() {
  $(body).page(); // use the most specific selector that contains all your divs
});
1 голос
/ 08 марта 2011

Используя jQuery, я придумал следующий код.На самом деле он не смотрит на класс Symbol, который вы упоминаете, но вы можете легко переместить символы в него по мере необходимости:

var symbols = {
    'alpha': 'a',
    'beta': 'b'
};

$(document).ready(function(){
    $('div.symbol').each(function(){
        var $this = $(this);
        var classes = $this.attr('class').split(' ');
        $(classes).each(function(ix, cls){
            if(typeof(symbols[cls]) == 'undefined'){ return; }
            $this.html(symbols[cls]);
            return;
        });
    });
});

Это учитывает использование имен классов и не приводит к сбою в неизвестных классах.Обратите внимание, что я использую $.each вместо $.click просто в качестве примера.Это будет действовать на каждый класс, который ему соответствует, поэтому, если у вас есть <div class="symbol alpha beta"></div>, он будет работать как на альфе, так и на бете!

Код доступен здесь: http://jsfiddle.net/w3ajG/

0 голосов
/ 08 марта 2011

var symbols = {'alpha': "&#x03B1;"}; - лучшая практика, и тогда вы можете легко получить к ним доступ, например, symbols.alpha не усложняйте ее,

затем

var symbols = {
        'alpha': "&#x03B1;",
        'beta' : "&#x03B2;",
};
$('div.symbol.alpha').click(function() {
      //alert(symbols.alpha); // console.debug(symbols.alpha);
      //or
      //alert(symbols['alpha']); // console.debug(symbols['alpha']);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...