Дизайн додатків Javascript MVC (полотно)


9

У мене виникають труднощі зрозуміти, як структурувати / архітектувати канвальний додаток, використовуючи подібний підхід MVC у Javascript. Користувальницький інтерфейс буде досить флюїдним та оживленим, ігри досить спрощеними, але з великим акцентом на тюнінг та анімацію. Я розумію, як MVC працює в принципі, але не на практиці. Я викрутив помилку з цього, прочитав дуже багато, і зараз я такий розгублений, як і коли я починав.

Деякі відомості про область застосування:

  • мультиекранна рамка гри - в цій рамках будуть розміщені декілька ігор: загальні "екрани" інтерфейсу включають: налаштування, інформацію, складність, головне меню тощо.
  • кілька методів введення
  • поширені елементи інтерфейсу, такі як рядок верхнього меню на деяких екранах
  • можливість використання різних методів візуалізації (canvas / DOM / webGL)

На даний момент у мене є AppModel, AppController та AppView. Звідси я планував додати кожен із «екранів» і долучити його до AppView. А як щодо таких речей, як верхня панель меню, вони повинні бути ще однією тріадою MVC? Де і як би я його кріпив без щільно з’єднуваних компонентів?

Чи прийнята практика мати одну тріаду MVC в іншій? тобто чи можу я додавати кожен "екран" до AppView? Чи "тріада" навіть прийнятий термін MVC ?!

Мій розум тане під варіантами ... Я відчуваю, що мені тут не вистачає чогось принципового. У мене вже розроблено рішення, не використовуючи підходу MVC, але я закінчив із суворо поєднаною супою - логікою та поглядами і в даний час поєднаний. Ідея полягала в тому, щоб відкрити його та дозволити легше змінювати погляди (наприклад, замінити вигляд полотна на подання на основі DOM).

Поточні бібліотеки, що використовуються: requ.js, createJS, підкреслюють, GSAP, вручну реалізують MVC

Будемо вдячні будь-які вказівки, приклади тощо, особливо щодо власне дизайну речі та розподілу "екранів" на належні M, V або C.

... або більш відповідний метод, відмінний від MVC

[NB: Якщо ви бачили це питання раніше, тому що я його задав у двох інших неправильних спільнотах stackexchange ... мій мозок перестав функціонувати]


1
Схоже, ви нарешті знайшли потрібний сайт. Гамедев не хотів вашого запитання?
Роберт Харві

@RobertHarvey подумав, що це, можливо, є більш актуальним тут ... принаймні, я сподіваюся!
wigglyworm

Відповіді:


3

MVC був охоплений у багатьох місцях, тому тут не повинно бути багато повторних. По суті, ви хочете, щоб ваш об'єктний графік, помічники та логіка містилися в ярусі моделі. Погляди будуть екранами, які висуваються для заповнення динамічної частини сторінки (і можуть містити невелику кількість логіки та помічників). І контролер, який є легкою реалізацією для обслуговування екранів на основі того, що було доступно з об'єктних графіків, помічників та логіки.

Модель

Це має бути там, де сидить м’ясо аплікації. Її можна розподілити на сервісний рівень, логічний рівень та сутність. Що це означає для вашого прикладу?

Субстанційний шар

Це має містити визначення моделей вашої гри та внутрішньої поведінки. Наприклад, якби у вас була гра для тральщика, саме тут описувались дошка та площа та визначення того, як вони змінюють свій внутрішній стан.

function Location(x,y){
 this.x = x;
 this.y = y;
}
function MineTile(x,y){
 this.flagged = false;
 this.hasMine = false;
 this.pristine = true;
 this.location = new Location(x,y);
}
MineTile.prototype.expose = function(){
 if( this.hasMine ) return false;
 this.pristine = false;
 return this.location;
};

Таким чином, MineTile дізнається свій внутрішній стан, наприклад, якщо він показує або був досліджений ( this.pristine), якщо це була одна з плиток, яка має шахту ( this.hasMine), але не визначатиме, чи мала вона мати шахту. Це залежить від логічного шару. (Щоб піти ще далі в ООП, MineTile міг успадкувати від загальної плитки).

Логічний шар

Це має містити складні способи взаємодії програми із змінами режимів, збереженням стану тощо. Отже, саме тут буде реалізована модель посередника, щоб підтримувати стан поточної гри. Тут буде грати логіка гри для визначення того, що відбувається, наприклад, під час гри, або для встановлення того, який MineTiles матиме шахту. Здійснюватиме виклики в рівень Entity, щоб отримати рівні екземпляри на основі логічно визначених параметрів.

var MineSweeperLogic = {
 construct: function(x,y,difficulty){
  var mineSet = [];
  var bombs = 7;
  if( difficulty === "expert" ) bombs = 15;
  for( var i = 0; i < x; i++ ){
   for( var j = 0; i j < y; j++ ){
    var mineTile = new MineTile(i,j);
    mineTile.hasMine = bombs-- > 0;
    mineSet.push(mineTile);
   }
  }
  return mineSet;
 },
 mineAt: function(x,y,mineSet){
  for( var i = 0; i < mineSet.length; i++ )
   if( mineSet[i].x === x && mineSet[i].y === y ) return mineSet[i];
 }
};

Сервісний рівень

Тут буде доступ до контролера. Він матиме доступ до логічного рівня для побудови ігор. Виклик високого рівня може здійснюватися в сервісний шар, щоб отримати повністю створену гру або модифікований стан гри.

function MineSweeper(x,y,difficulty){
 this.x = x;
 thix.y = y;
 this.difficulty = difficulty;
 this.mineSet = MineSweeperLogic.construct(x,y,difficulty);
}
MineSweeper.prototype.expose = function(x,y){
 return MineSweeperLogic.mineAt(x,y,this.mineSet).expose();
}

Контролер

Контролери повинні мати невелику вагу, по суті, це те, що піддається клієнту моделі. Контролерів буде багато, тому їх структурування стане важливим. Виклики функції контролера - це те, що потрапляє в дзвінки javascript на основі подій інтерфейсу користувача. Вони повинні розкрити поведінку, доступну на рівні обслуговування, а потім заповнити або в цьому випадку змінити погляди для клієнта.

function MineSweeperController(ctx){
 var this.context = ctx;
}
MineSweeperController.prototype.Start = function(x,y,difficulty){
 this.game = new MineSweeper(x,y,difficulty);
 this.view = new MineSweeperGameView(this.context,this.game.x,this.game.y,this.game.mineSet);
 this.view.Update();
};
MineSweeperController.prototype.Select = function(x,y){
 var result = this.game.expose(x,y);
 if( result === false ) this.GameOver();
 this.view.Select(result);
};
MineSweeperController.prototype.GameOver = function(){
 this.view.Summary(this.game.FinalScore());
};

Вид

Погляди повинні бути організовані щодо поведінки контролера. Вони, мабуть, будуть найбільш інтенсивною частиною вашої заявки, оскільки вона стосується полотна.

function MineSweeperGameView(ctx,x,y,mineSet){
 this.x = x;
 this.y = y;
 this.mineSet = mineSet;
 this.context = ctx;
}
MineSweeperGameView.prototype.Update = function(){
 //todo: heavy canvas modification
 for(var mine in this.mineSet){}
 this.context.fill();
}

Отже, у вас є ціла настройка MVC для цієї однієї гри. Або, принаймні, приклад голих кісток, написання всієї гри було б надмірним.

Після того, як це все буде зроблено, десь потрібно буде встановити глобальну область застосування. Це затримає термін експлуатації вашого поточного контролера, який є шлюзом до всього стеку MVC у цьому сценарії.

var currentGame;
var context = document.getElementById("masterCanvas").getContext('2d');
startMineSweeper.click = function(){
 currentGame = new MineSweeperController(context);
 currentGame.Start(25,25,"expert");
};

Використання шаблонів MVC дуже потужне, але не переживайте надто, щоб дотримуватися кожного їх нюансу. Зрештою, саме досвід гри визначить, чи буде програма успішною :)

Для розгляду: Не дозволяйте архітекторам архітектури лякати вас Джоелем Спольським


дякую @TravisJ - Я схвалив як своє приємне пояснення MVC, що стосується ігор. Досі незрозумілі певні моменти, я думаю, як ви кажете, я занурююся в нюанси шаблонів, і це зупиняє мене рухатись вперед. Одне, що я бачив, - це використання this.view.Select () у контролері - чи потрібен цей тип жорсткої муфти чи існує спосіб роз'єднання далі?
wigglyworm

@wigglyworm - Завжди може бути більше розв'язки! : D Але дійсно, контролер повинен бути тим, хто повідомляє модель, а потім оновлює уявлення, так що, ймовірно, там, де найбільше з'єднання відбувається в MVC.
Травіс J

2

Ось, що ви вже зробили неправильно - ви перекочували MVC вручну, перебуваючи в заплутаному стані, і без жодного MVC під поясом.

Погляньте на PureMVC, це мовний агностик і може стати хорошою платформою для того, щоб намочити ноги, фактично роблячи MVC.

Його код невеликий і зрозумілий, і це дозволить вам підлаштувати його під свої потреби під час прогресу.

Почніть писати невелику просту гру з нею, тральщик буде добре. Багато з того, що сказав Травіс Дж, добре, особливо про Модель. Я хотів би лише додати, що вам потрібно пам’ятати, що контролери (принаймні в PureMvc) без громадянства, вони існують, роблять свою КОРОТКУ роботу та йдуть. Вони - знаючі. Вони як функції. "Заповніть сітку, тому що модель змінилася", "оновіть модель, тому що була натиснута кнопка"

Погляди (Медіатори в PureMVC) - найглуміші, а Модель лише трохи розумніша. Обидва абстрактно реалізують реалізацію, тому ви (контролери) ніколи не торкаєтесь безпосередньо інтерфейсу користувача або бази даних.

Кожен елемент вашого інтерфейсу (наприклад, у програмі winforms) має представлення (Медіатор - ви бачите, чому це зараз кращий термін?), Але Медіатори також можуть бути створені для мета-проблем, таких як "Колір управління" або "Фокус" Менеджер ", які працюють через елементи інтерфейсу. Думайте тут шарами.

Події користувальницького інтерфейсу та БД можуть автоматично викликати контролери (якщо ви використовуєте інтелектуальну схему іменування), а певні контролери можуть бути припинені - медіатор може бути зроблений безпосередньо для прослуховування події зміни даних моделі та доставки її пакету даних.

Хоча це своєрідна обман і вимагає від Моделі трохи знати про те, що там, і Посередник зрозуміти, що робити з пакетом даних, але це убереже вас від того, щоб у багатьох випадках не завалитись мирськими контролерами.

Модель: Тупий, але багаторазовий; Контролери: розумні, але менш використані (вони - додаток); Посередники: німий, але багаторазовий. Повторне використання в цьому випадку означає переносити в інший додаток.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.