2015-08-30 3 views
0

Я читал somewhere Инверсия управления (IoC) является (вроде) принципом каркаса.Минималистский каркас

Правильно ли (воспользовавшись этим), я разработал каркас для X только потому, что используется шаблон IoC?

Могу ли я запросить минимальный пример каркаса (например, код на C++)?

Или вместо этого я могу попытаться быть более конкретным, предоставляя некоторый код (полный проект Qt) и спрашивая, существует ли там инфраструктура.

Класс FrameworkForX (внизу, в конце) можно назвать каркасом?

framework.pro

QT  += core gui 

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 

TARGET = framework 
TEMPLATE = app 

SOURCES += main.cpp\ 
     widget.cpp \ 
    frameworkforx.cpp \ 
    solvemyproblem.cpp 

HEADERS += widget.h \ 
    frameworkforx.h \ 
    solvemyproblem.h 

main.cpp

#include "widget.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    Widget w; 
    w.show(); 

    return a.exec(); 
} 

widget.h

#ifndef WIDGET_H 
#define WIDGET_H 

#include <QWidget> 

class QLineEdit; 
class QLabel; 
class SolveMyProblem; 

class Widget : public QWidget 
{ 
    Q_OBJECT 
public: 
    Widget(QWidget *parent = 0); 
    ~Widget(); 

private: 
    QLineEdit *lineEdit; 
    QLabel *label; 
    SolveMyProblem *solveMyProblem; 

public slots: 
    void doit(); 
    void onResult(int result); 
}; 

#endif // WIDGET_H 

widget.cpp

#include "widget.h" 

#include "QVBoxLayout" 
#include "QPushButton" 
#include "QLineEdit" 
#include "QLabel" 

#include "solvemyproblem.h" 

Widget::Widget(QWidget *parent) 
    : QWidget(parent), solveMyProblem(new SolveMyProblem) 
{ 
    QVBoxLayout *vLayout = new QVBoxLayout(this); 

    lineEdit = new QLineEdit; 
    vLayout->addWidget(lineEdit); 

    QPushButton *bt = new QPushButton("Do It!"); 
    connect(bt, &QPushButton::clicked, this, &Widget::doit); 
    vLayout->addWidget(bt, 1, Qt::AlignRight); 

    label = new QLabel("The result will be shown here."); 
    connect(solveMyProblem, &SolveMyProblem::result, this, &Widget::onResult); 
    vLayout->addWidget(label); 

    resize(400, 100); 
    setWindowTitle("Is it (FrameworkForX) a framework?"); 
} 

Widget::~Widget() 
{ 

} 

void Widget::doit() 
{ 
    QString text = lineEdit->text(); 
    solveMyProblem->doSomething(text); 
} 

void Widget::onResult(int result) 
{ 
    QString text = QString::number(result); 
    label->setText(text); 
} 

solvemyproblem.h

#ifndef SOLVEMYPROBLEM_H 
#define SOLVEMYPROBLEM_H 

#include "frameworkforx.h" 

class SolveMyProblem : public FrameworkForX 
{ 
public: 
    SolveMyProblem(); 

    int doSpecificJob(const QString &text); 
}; 

#endif // SOLVEMYPROBLEM_H 

solvemyproblem.cpp

#include "solvemyproblem.h" 

SolveMyProblem::SolveMyProblem() 
{ 

} 

int SolveMyProblem::doSpecificJob(const QString &text) 
{ 
    int i = text.size(); 
    return i; 
} 

frameworkforx.h

#ifndef FRAMEWORKFORX_H 
#define FRAMEWORKFORX_H 

#include "QObject" 

class QString; 

class FrameworkForX : public QObject 
{ 
    Q_OBJECT 
public: 
    FrameworkForX(); 

    void doSomething(const QString &text); 

protected: 
    virtual int doSpecificJob(const QString &text) = 0; 

signals: 
    void result(int i); 

}; 

#endif // FRAMEWORKFORX_H 

frameworkforx.cpp

#include "frameworkforx.h" 

FrameworkForX::FrameworkForX() 
{ 

} 

void FrameworkForX::doSomething(const QString &text) 
{ 
    int value = doSpecificJob(text); 
    emit result(value); 
} 
+0

Это может помочь http://dirkriehle.com/computer-science/research/dissporation/diss-a4.pdf – KcFnMi

+0

Это может помочь https://sourcemaking.com/design_patterns/template_method. – KcFnMi

ответ

1

Ваш пример близок к framewor к. И это близко к IoC. Но, на мой взгляд, это не точная картина из этой части:

Widget::Widget(QWidget*) 
: ... solveMyProblem(new SolveMyProblem) 

Widget все еще имеет контроль над своей стратегией. Он даже строит его. Поэтому инверсии нет. Правильная реализация IoC будет принимать стратегию, например. как параметр. Тогда возникает смысл требовать базовый класс или интерфейс:

Widget::Widget(QWidget*, FrameworkForX* mySolver) 
: ... solveMyProblem(mySolver) 
//of course, the declaration of solveMyProblem has to be adapted 

До сих пор для части IoC. Давайте перейдем к структуре. Возможное определение каркаса:

Рамка представляет собой программный компонент с точками расширения и точками вариации.

Программный компонент может быть любым. Это может быть класс, библиотека, целый набор библиотек ... Что предлагает IoC, это вариационная точка. Вы можете варьировать функциональность класса (в данном случае Widget) путем предоставления пользовательской реализации. Вы можете подключить эту реализацию в структуру, чтобы создать полностью функциональный программный компонент (тогда как структура обычно является лишь своего рода скелетом).

So: Да.На мой взгляд, каждая реализация IoC может рассматриваться как структура. В вашем конкретном примере структура будет состоять из Widget и FrameworkForX (где FrameworkForX может быть даже просто интерфейсом). SolveMyProblem - это пользовательская реализация, которая подключается к этой структуре.