Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
thechicho
0 / 0 / 0
Регистрация: 15.03.2015
Сообщений: 14
Завершенные тесты: 1
#1

Предложить рефакторинг с учетом, что количество языков будет расширяться - C++

17.08.2016, 10:31. Просмотров 217. Ответов 9
Метки нет (Все метки)

Предложите ваши варианты решения заданий
2. Есть класс CodeGenerator, который умеет генерить код на разных языках.
Предложите рефакторинг с учетом, что количество языков будет расширяться

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class CodeGenerator
{
public:
    enum Lang {JAVA, C_PLUS_PLUS, PHP};
    CodeGenerator(Lang language) { _language=language; }
    std::string generateCode()
    {
        switch(_language) {
        case JAVA:        //return generated java code
        case C_PLUS_PLUS: //return generated C++ code
        case PHP:         //return generated PHP code
        }
        throw new std::logic_error("Bad language");
    }
    std::string someCodeRelatedThing() // used in generateCode()
    {
        switch(_language) {
        case JAVA:        //return generated java-related stuff
        case C_PLUS_PLUS: //return generated C++-related stuff
        case PHP:         //return generated PHP-related stuff
        }
        throw new std::logic_error("Bad language");
    }
 
private:
    Lang _language;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.08.2016, 10:31
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Предложить рефакторинг с учетом, что количество языков будет расширяться (C++):

Что делать?(учу C++ и кое что ни понимаю может стоит начать с более "низких языков" например basic) - C++
Всем привет народ вот я учу C++ и кое что ни понимаю может стоит начать с более "низких языков" например basic?

RegEnumKeyEx: что будет, если количество вызовов превысит количество подключей? - C++ WinAPI
Зачем перечислять ключи ? Правильно ли понимаю ? Функция RegEnumKeyEX ассоциирует некоторое число с каким то ключом(Точнее...

Что предложить спонсору? - SEO
Готовлю небольшой бизнес план под интернет-проект. Сайт будет, скажем так, тематическим. Возможным спонсором будет выступать сеть...

Рефакторинг кода. Что можно улучшить? - PHP ООП
Всем привет!) Начал потихоньку использовать ООП, хочу услышать мнение более сведующих людей, что и, как в коде улучшить? Есть вопросы...

найти вероятность того, что количество спелых арбузов будет находиться в пределах - Теория вероятностей
В партиии из 768 арбузов каждый арбуз оказывается неспелым с вероятностью 0,25.найти вероятность того, что количество спелых арбузов будет...

Найти вероятность того, что из 10 ламп количество шестидесятиватных будет составлять более 10 - MS Excel
Народ, помогите с задачей. Её нужно решить в excel. Буду очень благодарен! В ящике лежит 100 электроламп, из каких 45 стоватных, 25...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
John Prick
801 / 734 / 145
Регистрация: 27.07.2012
Сообщений: 2,107
Завершенные тесты: 3
17.08.2016, 11:17 #2
Ну тут основная идея - избавиться от switch. Можно предложить шаблоны, хотя м.б. это и не самый хороший способ.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
struct Lang {
    enum E {JAVA, C_PLUS_PLUS, PHP};
};
 
template <Lang::E Language>
class CodeGenerator
{
public:
    std::string generateCode()
    {
        throw /*new*/ std::logic_error("Bad language"); // исключения м.б. лучше по значению кидать
    }
    std::string someCodeRelatedThing() // used in generateCode()
    {
        throw /*new*/ std::logic_error("Bad language");
    }
};
 
template <>
class CodeGenerator<Lang::JAVA>
{
public:
    std::string generateCode() { /*return generated java code*/ }
    std::string someCodeRelatedThing() // used in generateCode()
    { /*return generated java-related stuff*/ }
};
 
template <>
class CodeGenerator<Lang::C_PLUS_PLUS>
{
public:
    std::string generateCode() { /*return generated C++ code*/ }
    std::string someCodeRelatedThing() // used in generateCode()
    { /*return generated C++-related stuff*/ }
};
 
// и так далее специализации для каждого нового языка.
Добавлено через 5 минут
Другой вариант - вместо перечисления создать полноценные классы JAVA, PHP и т.д. функционала для генерации кода и использовать их как стратегии для генератора. Тогда и специализаций не понадобится. Уйдёт лишнее дублирование кода.
1
notAll
411 / 132 / 29
Регистрация: 27.05.2016
Сообщений: 349
Завершенные тесты: 2
17.08.2016, 12:06 #3
Стратегия:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class Language
{
public:
    virtual ~Language() = default;
    virtual std::string code() const = 0;
};
 
class JAVA : public Language
{
public:
    std::string code() const override
    {
        return "generated java code";
    }
};
 
class C_PLUS_PLUS : public Language
{
public:
    std::string code() const override
    {
        return "generated C++ code";
    }
};
 
class PHP : public Language
{
public:
    std::string code() const override
    {
        return "generated PHP code";
    }
};
 
class CodeGenerator
{
public:
    CodeGenerator(Language* language) { _language=language; }
    std::string generateCode()
    {
        if (_language)
            return _language->code();
        else
            throw new std::logic_error("Bad language");
    }
    std::string someCodeRelatedThing()
    {
        return generateCode();
    }
 
    ~CodeGenerator() {delete _language;}
 
private:
    Language* _language;
};
 
int main()
{
    CodeGenerator cgJava(new JAVA);
    CodeGenerator cgPHP(new PHP);
    std::cout << cgJava.generateCode() << "\n";
    std::cout << cgPHP.generateCode() << "\n";
}
0
John Prick
801 / 734 / 145
Регистрация: 27.07.2012
Сообщений: 2,107
Завершенные тесты: 3
17.08.2016, 13:22 #4
Цитата Сообщение от notAll Посмотреть сообщение
Стратегия
Имхо стратегии лучше всё-таки реализовывать через статическое связывание (через шаблоны). Это позволит не возиться с динамической памятью и избавит от некоторых непреднамеренных ошибок типа:
C++
1
2
3
4
Language lang;
{
   CodeGenerator codegen(&lang);
} // <-- Ой! CodeGenerator::~CodeGenerator() {delete _language;}
Да и экономия на виртуальном вызове.

Добавлено через 39 секунд
override - я что-то пропустил? Так можно уже в С++?
0
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
17.08.2016, 13:33 #5
Цитата Сообщение от John Prick Посмотреть сообщение
Так можно уже в С++?
Да.
0
notAll
411 / 132 / 29
Регистрация: 27.05.2016
Сообщений: 349
Завершенные тесты: 2
17.08.2016, 13:41 #6
Цитата Сообщение от John Prick Посмотреть сообщение
Это позволит не возиться с динамической памятью
Можно переписать с использованием умных указателей и никаких проблем:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class Language
{
public:
    virtual ~Language() = default;
    virtual std::string code() const = 0;
};
 
class JAVA : public Language
{
public:
    std::string code() const override {return "generated java code";}
};
 
class C_PLUS_PLUS : public Language
{
public:
    std::string code() const override {return "generated C++ code";}
};
 
class PHP : public Language
{
public:
    std::string code() const override {return "generated PHP code";}
};
 
class CodeGenerator
{
public:
    CodeGenerator(std::unique_ptr<Language> language) :
        _language(std::move(language))
    {}
 
    std::string generateCode() const
    {
        if (_language)
            return _language->code();
        else
            throw new std::logic_error("Bad language");
    }
 
    std::string someCodeRelatedThing() const
    {
        return generateCode() + " stuff";
    }
 
private:
    std::unique_ptr<Language> _language;
};
 
int main()
{
    CodeGenerator cgJava(std::make_unique<JAVA>());
    CodeGenerator cgPHP(std::make_unique<PHP>());
 
    std::cout << cgJava.generateCode() << "\n";
    std::cout << cgPHP.someCodeRelatedThing() << "\n";
}
0
John Prick
801 / 734 / 145
Регистрация: 27.07.2012
Сообщений: 2,107
Завершенные тесты: 3
17.08.2016, 13:53 #7
Цитата Сообщение от notAll Посмотреть сообщение
Можно переписать с использованием умных указателей и никаких проблем
Ну основной мой посыл был не совсем в этом. Я просто немного не закончил мысль. Динамические стратегии (так их назовём) можно применить, например, если генератору кода надо будет по ходу выполнения сменить стратегию. Если такой опции не требуется, то имхо лучше использоать статические стратегии.

Всё-таки есть некая разница в удобстве применения:
C++
1
2
3
CodeGenerator cgJava(std::make_unique<JAVA>());
// Или
CodeGenerator<JAVA> cgJava;
Но не навязываю свой мнение.
0
notAll
411 / 132 / 29
Регистрация: 27.05.2016
Сообщений: 349
Завершенные тесты: 2
17.08.2016, 14:10 #8
Пока я вижу только проблемы при использовании статической стратегии. Если, допустим со временем, нам понадобиться поменять интерфейс CodeGenerator - надо будет вносить изменения в каждую специализацию, а их может быть много. А если захотим создать массив CodeGenerator, как быть, - типы CodeGenerator<> то у нас разные будут.
0
John Prick
801 / 734 / 145
Регистрация: 27.07.2012
Сообщений: 2,107
Завершенные тесты: 3
17.08.2016, 14:21 #9
Цитата Сообщение от notAll Посмотреть сообщение
Если, допустим со временем, нам понадобиться поменять интерфейс CodeGenerator - надо будет вносить изменения в каждую специализацию, а их может быть много.
Нет. Тут не будет никаких специализаций:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class JAVA
{
public:
    std::string code() {return "generated java code";}
};
 
template <class LangPolicy>
class CodeGenerator : public LangPolicy
{
public:
    std::string generateCode() const
    {
        return code();
    }
};
Цитата Сообщение от notAll Посмотреть сообщение
А если захотим создать массив CodeGenerator, как быть, - типы CodeGenerator<> то у нас разные будут.
Это если захотим создать. Перед тем как рефакторить класс, надо как раз подумать над тем, как этот класс будет применяться. Но и тут ничего не мешает создать базовый абстрактный класс CodeGeneratorAbstract, а функцию generateCode сделать виртуальной. Шаблонный класс будет наследовать от него.
0
hoggy
Нарушитель
6590 / 2771 / 476
Регистрация: 15.11.2014
Сообщений: 6,125
Завершенные тесты: 1
17.08.2016, 18:20 #10
Цитата Сообщение от notAll Посмотреть сообщение
Если, допустим со временем, нам понадобиться поменять интерфейс CodeGenerator - надо будет вносить изменения в каждую специализацию, а их может быть много.
в случая с дин. полиморфизмом - каждого наследника.

те же яйца только сбоку.

Цитата Сообщение от notAll Посмотреть сообщение
А если захотим создать массив CodeGenerator, как быть
не нужно решать проблемы будущего, которое может и не наступить.


ps:
я за абстрактный интерфейс CodeGenerator и шаблоно-наследников.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.08.2016, 18:20
Привет! Вот еще темы с ответами:

Найти вероятность того, что количество пшеницы, собранной с этого участка, будет от 95 до 110 ц - Теория вероятностей
Уражайность пшеницы на обследуемом участке является случайной велечиной с нормальным распределением, математическое ожидание которой равно...

Какая будет оптимальная разметка диска для Windows 10 с учетом GPT и UEFI? - Windows 10
Подскажите пожалуйста какая будет оптимальная разметка диска для windows 10? С учетом GPT и UEFI. На компьютере не будет больше никаких...

Как позволить расширяться richtextbox'у - C#
Собственно, сабж. Хочется, как например в блокноте, чтобы было: Подскажите, пожалуйста

Какое наибольшее количество пар обуви сможет предложить продавец, чтобы покупатель смог одеть их одновременно? - Python
В обувном магазине страны великанов продается обувь разного размера. Известно, что одну пару обуви можно надеть на другую, если она хотя бы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
17.08.2016, 18:20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru