模塊化兩個概念:git
軟件設計模塊化github
軟件代碼模塊化數據庫
軟件設計模塊化——分層——MVC——PureMVC設計模式
軟件代碼模塊化——JavaScript模塊化——CommonJS——WebPack服務器
分層是將一個複雜的程序進行層次劃分。爲每一層進行設計,每層都是內聚的並且只依賴與它的下層。採用標準的架構模式來完成與上層的鬆散關聯。將全部與領域模型相關的代碼都集中在一層,而且將它與用戶界面層、應用層和基礎結構層的代碼分離。領域對象能夠將重點放在表達領域模型上,不須要關心它們本身的顯示、存儲和管理應用任務等內容。這樣使模型發展得足夠豐富和清晰,足以抓住本質的業務知識並實現它。架構
MVC全名是Model View Controller,是模型(Model)-視圖(View)-控制器(Controller)的縮寫,一種軟件設計典範,用一種業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯彙集到一個部件裏面,在改進和個性化定製界面及用戶交互的同時,不須要從新編寫業務邏輯。MVC被獨特的發展起來用於映射傳統的輸入、處理和輸出功能在一個邏輯的圖形化用戶界面的結構中。mvc
MVC主要把邏輯層和表現層進行了解耦,將一個問題劃分紅了不一樣的關注點。加強了應用的穩定性,易修改性和易複用性。app
視圖(View):就是用戶看到並與之交互的界面。它不作數據邏輯方面的工做,一般來講就是顯示從模型中得到的數據,或者獲取用戶的操做。當模型更新時,它須要得知模型已經更新並獲取更新後的數據以刷新界面。所以須要在模型處註冊關注該模型的視圖,以便模型通知視圖更新顯示。框架
模型(Model):用於封裝與應用程序的業務邏輯相關的數據以及對數據的處理方法。「模型」有對數據直接訪問的權力,例如對數據庫的訪問。所以它經常也用來與遠程服務器做交互,做爲一個與外界訪問的代理。加載外部資源,如圖片,xml等也是在這裏操做。模型不關心本身會被如何操做或顯示,只要在數據更新時,向關注它的視圖發送通知則可。模塊化
控制器(Controller):自己不做業務邏輯操做,它負責關聯視圖和模型,就像一個紐帶同樣。同時它也負責應用的流程。一般控制器會得到模型和視圖的實例,而後條用它們內部的函數。
PureMVC 是在基於模型、視圖和控制器 MVC 模式創建的一個輕量級的應用框架,這是一個開源框架,它最初是被用於 ActionScript 3 語言使用的 Adobe Flex、Flash 和 AIR 之上,如今已經移植到幾乎全部主要的軟件平臺之上。
在 PureMVC 實現的經典 MVC 元設計模式中,Model、View 和 Controller 分別由一個單例類來管理,合稱爲核心層或核心角色。 另外,在 PureMVC 中還提供了一個單例類 —— Façade,主要做用是做爲與核心層通訊的惟一接口,簡化開發複雜度。
除了這幾個主要對象之外,框架還有以下類 Proxy、Mediator 和 Command。
Proxy 對象負責操做數據模型,與遠程服務通訊存取數據,這樣能夠保證 Model 層的可移植性。一般 Proxy 對象的引用保存在 Model 中。
View 保存對 Mediator 對象的引用。由 Mediator 對象來操做具體的視圖組件(View Component,它的做用還包括:添加事件監聽器,發送或接收 Notification,直接改變視圖組件的狀態。經過這樣,就能夠把視圖和控制它的邏輯分離開來。
Command 對象是無狀態的,只在須要時才被建立。Command 能夠獲取 Proxy 對象並與之交互,發送 Notification,執行其餘的 Command。常常用於複雜的或系統範圍的操做,如應用程序的「啓動」和「關閉」。應用程序的業務邏輯應該在這裏實現。
除了基本的對象結構之外,爲了解耦合,PureMVC 框架中引入了事件機制,這是個很是簡單觀察者設計模式,全部的事件都是一個 Notification,不一樣對象之間經過 Notification 來同步操做和交換信息。例如若是想更新界面中某個 Mediator,首先咱們定義 Notification 用於此目的,而後註冊 Mediator 監聽該 Notification,而後就能夠在程序中任何地方生成一個 Notification,經過事件機制,Mediator 就會接收到 Notification,而後更新須要的部分。整個過程 Mediator 只和 Notification 有關,沒有其餘依賴,有效的下降了對象之間的依賴程度。
PureMVC中有一個單例模式類——Facade,Facade提供了與核心層通訊的惟一接口,以簡化開發複雜度。
Facade子類——AppFacade.js
///<reference path="../../../../typings/main.d.ts"/> import {StartupCommand} from '../controller/command/startupCommand'; import {DirectorMediator} from '../view/mediator/DirectorMediator'; export class AppFacade extends puremvc.Facade implements puremvc.IFacade { private static STARTUP_COMMAND: string = 'STARTUP_COMMAND:'; private static DIRECTOR_MEDIATOR: string = 'DIRECTOR_MEDIATOR'; public constructor(key) { super(key); } public initializeController() { puremvc.Facade.prototype.initializeController.call(this); this.registerCommand(AppFacade.STARTUP_COMMAND, StartupCommand); } public initializeModel() { puremvc.Facade.prototype.initializeModel.call(this); } public initializeView() { puremvc.Facade.prototype.initializeView.call(this); this.registerMediator(new DirectorMediator()); } public getDirector(): any { if (this.hasMediator(AppFacade.DIRECTOR_MEDIATOR)) { var directorMediator = this.retrieveMediator(AppFacade.DIRECTOR_MEDIATOR); return directorMediator.getViewComponent(); } } public startup() { this.sendNotification(AppFacade.STARTUP_COMMAND); } public static getInstance(key): any { var instanceMap = puremvc.Facade.instanceMap; var instance = instanceMap[key]; if (instance) { return instance; } return instanceMap[key] = new AppFacade(key); } }
類方法getInstance用於返回AppFacade的單例。Facade是pureMVC的核心,標準版的Facade只會存在一個,多核版本Facade會有多個,它的實例會在instanceMap中保存。
自定義方法getDirector()返回一個Sprite實例,做爲根場景。
PureMVC已經在框架內部實現了Observer/Notification機制,只須要使用一個很是簡單的方法從Proxy, Mediator, Command和Facade發送Notification,甚至不須要建立一個Notification實例。
Facade保存了Command與Notification之間的映射。當Notification(通知)被髮出時,對應的Command(命令)就會自動地由Controller執行。
建立的Facade子類被用來簡化「啓動」的過程。應用程序調用Facade子類的startup方法,並傳遞自身的一個引用即完成啓動,使得應用程序不須要過多瞭解PureMVC。
入口類調用AppFacade
///<reference path="../../../typings/main.d.ts"/> import {AppFacade} from './facade/appFacade'; class App extends egret.DisplayObjectContainer { public constructor() { super(); this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this); } private onAddToStage(event: egret.Event) { this.createGameScene(); } private createGameScene(): void { var key:string = 'GY_EGRET_PATTERN'; var stageWidth: number = this.stage.stageWidth; var stageHeight: number = this.stage.stageHeight; var appFacade = AppFacade.getInstance(key); var director = appFacade.getDirector(); director.width = stageWidth; director.height = stageHeight; director.render(); this.addChild(director); appFacade.startup(); } } egret.registerClass(App, "App"); window["App"] = App;
Guyoung Studio
Official Site: www.guyoung.net
Email: guyoung[at]aliyun.com