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

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

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

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

17.08.2016, 10:31. Просмотров 205. Ответов 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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.08.2016, 10:31     Предложить рефакторинг с учетом, что количество языков будет расширяться
Посмотрите здесь:

рефакторинг -> переименование - C++
Добрый день. Вопрос: в C# (IDE Visual Studio 2012) по нажатию F2 можно было мгновенно переименовать любую переменную под курсором. В...

Рефакторинг кода - C++
Нужно сделать рефакторинг большого корпоративного проекта (а лучше для нескольких сразу). Для начала хотелось бы посмотреть наличие...

Оптимизация, рефакторинг кода - C++
Программа написанная для лаб.работы по предмету "Теория Графов". Программа с задачей перейти из одного способа задания(мб другое слово)...

Необходимо провести рефакторинг - C++
Существует прогамма: #include <iostream> using namespace std; //Structure for a bank certificate of deposit: struct...

Рефакторинг кода задачки - C++
Здравствуйте! Скажите пожалуйста, как можно отрефакторить следующую программу ? (без STL и ООП) #include <iostream> using...

что будет? - C++
что случится если запустить такой код :scratch: long int *p, i = 0; while(1) { i++; p ;

Что будет? - C++
Что будет если пару раз вызвать вот такую штуку? mLastTrack->sampleTable = new SampleTable(mDataSource); Спасибо!

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
John Prick
773 / 706 / 129
Регистрация: 27.07.2012
Сообщений: 2,022
Завершенные тесты: 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 и т.д. функционала для генерации кода и использовать их как стратегии для генератора. Тогда и специализаций не понадобится. Уйдёт лишнее дублирование кода.
notAll
382 / 103 / 21
Регистрация: 27.05.2016
Сообщений: 266
Завершенные тесты: 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";
}
John Prick
773 / 706 / 129
Регистрация: 27.07.2012
Сообщений: 2,022
Завершенные тесты: 3
17.08.2016, 13:22     Предложить рефакторинг с учетом, что количество языков будет расширяться #4
Цитата Сообщение от notAll Посмотреть сообщение
Стратегия
Имхо стратегии лучше всё-таки реализовывать через статическое связывание (через шаблоны). Это позволит не возиться с динамической памятью и избавит от некоторых непреднамеренных ошибок типа:
C++
1
2
3
4
Language lang;
{
   CodeGenerator codegen(&lang);
} // <-- Ой! CodeGenerator::~CodeGenerator() {delete _language;}
Да и экономия на виртуальном вызове.

Добавлено через 39 секунд
override - я что-то пропустил? Так можно уже в С++?
DrOffset
6913 / 4106 / 935
Регистрация: 30.01.2014
Сообщений: 6,904
17.08.2016, 13:33     Предложить рефакторинг с учетом, что количество языков будет расширяться #5
Цитата Сообщение от John Prick Посмотреть сообщение
Так можно уже в С++?
Да.
notAll
382 / 103 / 21
Регистрация: 27.05.2016
Сообщений: 266
Завершенные тесты: 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";
}
John Prick
773 / 706 / 129
Регистрация: 27.07.2012
Сообщений: 2,022
Завершенные тесты: 3
17.08.2016, 13:53     Предложить рефакторинг с учетом, что количество языков будет расширяться #7
Цитата Сообщение от notAll Посмотреть сообщение
Можно переписать с использованием умных указателей и никаких проблем
Ну основной мой посыл был не совсем в этом. Я просто немного не закончил мысль. Динамические стратегии (так их назовём) можно применить, например, если генератору кода надо будет по ходу выполнения сменить стратегию. Если такой опции не требуется, то имхо лучше использоать статические стратегии.

Всё-таки есть некая разница в удобстве применения:
C++
1
2
3
CodeGenerator cgJava(std::make_unique<JAVA>());
// Или
CodeGenerator<JAVA> cgJava;
Но не навязываю свой мнение.
notAll
382 / 103 / 21
Регистрация: 27.05.2016
Сообщений: 266
Завершенные тесты: 2
17.08.2016, 14:10     Предложить рефакторинг с учетом, что количество языков будет расширяться #8
Пока я вижу только проблемы при использовании статической стратегии. Если, допустим со временем, нам понадобиться поменять интерфейс CodeGenerator - надо будет вносить изменения в каждую специализацию, а их может быть много. А если захотим создать массив CodeGenerator, как быть, - типы CodeGenerator<> то у нас разные будут.
John Prick
773 / 706 / 129
Регистрация: 27.07.2012
Сообщений: 2,022
Завершенные тесты: 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 сделать виртуальной. Шаблонный класс будет наследовать от него.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.08.2016, 18:20     Предложить рефакторинг с учетом, что количество языков будет расширяться
Еще ссылки по теме:

какие альтернативы GOTO можете предложить? - C++
ситуация следующая. есть главное меню: 1. Список Блюд 2. Список напитков 3. Выход При переходе в первый пункт,...

Рефакторинг кода вывода простых чисел - C++
#include &lt;iostream&gt; #include &lt;ctime&gt; int main() { clock_t t = clock(); { std::size_t size = 1000; ...

Калькулятор: Рефакторинг, принцип единой ответственности - C++
Дали задание сделать калькулятор с помощью паттерна команда,сам калькулятор сделал,паттерн осуществил, но проблема в классах патттерна не...

Что будет выведено на экран? - C++
Увидел только что такую вот интересную задачку на одном форуме #include &lt;iostream&gt; struct aaa { aaa(int i) { ...

что будет выведено на экран - C++
7)Баллов: 1 Что будет выведено на экран в результате работы следующего программного фрагмента: char c= 'a' ; cout &lt;&lt; ( int )c;


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

Или воспользуйтесь поиском по форуму:
hoggy
6369 / 2587 / 452
Регистрация: 15.11.2014
Сообщений: 5,722
Завершенные тесты: 1
17.08.2016, 18:20     Предложить рефакторинг с учетом, что количество языков будет расширяться #10
Цитата Сообщение от notAll Посмотреть сообщение
Если, допустим со временем, нам понадобиться поменять интерфейс CodeGenerator - надо будет вносить изменения в каждую специализацию, а их может быть много.
в случая с дин. полиморфизмом - каждого наследника.

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

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


ps:
я за абстрактный интерфейс CodeGenerator и шаблоно-наследников.
Yandex
Объявления
17.08.2016, 18:20     Предложить рефакторинг с учетом, что количество языков будет расширяться
Ответ Создать тему
Опции темы

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