13.7 Каркас области приложения.

   


Назад  |  Вперёд

Мы перечислили виды классов, из которых можно создать библиотеки, нацеленные на проектирование и повторное использование прикладных программ. Они предоставляют определенные "строительные блоки" и объясняют как из них строить. Разработчик прикладного обеспечения создает каркас, в который должны вписаться универсальные строительные блоки. Задача проектирования прикладных программ может иметь иное, более обязывающее решение: написать программу, которая сама будет создавать общий каркас области приложения. Разработчик прикладного обеспечения в качестве строительных блоков будет встраивать в этот каркас прикладные программы. Классы, которые образуют каркас области приложения, имеют настолько обширный интерфейс, что их трудно назвать типами в обычном смысле слова. Они приближаются к тому пределу, когда становятся чисто прикладными классами, но при этом в них фактически есть только описания, а все действия задаются функциями, написанными прикладными программистами.

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

           class filter {
           public:
             class Retry {
             public:
               virtual const char* message() { return 0; }
             };

           virtual void start() { }
           virtual int retry() { return 2; }
           virtual int read() = 0;
           virtual void write() { }
           virtual void compute() { }
           virtual int result() = 0;
           };

Нужные для производных классов функции описаны как чистые виртуальные, остальные функции просто пустые. Каркас содержит основной цикл обработки и зачаточные средства обработки ошибок:

           int main_loop(filter* p)
           {
             for (;;) {
                 try {
                     p->start();
                     while (p->read()) {
                           p->compute();
                           p->write();
                     }
                     return p->result();
                 }
                 catch (filter::Retry& m) {
                   cout << m.message() << '\n';
                   int i = p->retry();
                   if (i) return i;
                 }
                 catch (...) {
                   cout << "Fatal filter error\n";
                   return 1;
                 }
             }
           }

Теперь прикладную программу можно написать так:

           class myfilter : public filter {
              istream& is;
              ostream& os;
              char c;
              int nchar;

           public:
              int read() { is.get(c); return is.good(); }
              void compute() { nchar++; };
              int result()
                  { os << nchar
                       << "characters read\n";
                       return 0;
                  }

              myfilter(istream& ii, ostream& oo)
                : is(ii), os(oo), nchar(0) { }
           };

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

           int main()
           {
             myfilter f(cin,cout);
             return main_loop(&f);
           }

Настоящий каркас, чтобы рассчитывать на применение в реальных задачах, должен создавать более развитые структуры и предоставлять больше полезных функций, чем в нашем простом примере. Как правило, каркас образует дерево узловых классов. Прикладной программист поставляет только классы, служащие листьями в этом многоуровневом дереве, благодаря чему достигается общность между различными прикладными программами и упрощается повторное использование полезных функций, предоставляемых каркасом. Созданию каркаса могут способствовать библиотеки, в которых определяются некоторые полезные классы, например, такие как scrollbar ($$12.2.5) и dialog_box ($$13.4). После определения своих прикладных классов программист может использовать эти классы.


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.