2012-04-12 63 views
2

我正在使用ZF的MVC应用程序,并大量混淆我的代码应该如何构造。ZF MVC - 对象和映射器

我有一个程序性应用程序,它基本上是一个巨大的长文件,具有我希望我的应用程序执行的所有操作的功能....就像getUsername($ id)等等。所以现在我正在重建整个事物在ZF中,因为我当前的代码库不可行,垃圾并且很难调试。

我是新来的MVC和大量混淆应该如何布局,什么应该谈什么等等。所以我知道关于模板和控制器需要瘦,以及你应该有胖模型但我很困惑逻辑的需要。

我正在做一个游戏,平时有喜欢的对象....用户,村,军队,MapSquares,资源等

如果我完全想它理论,我只想说: 1用户对象包含许多村庄,每个村庄属于一个广场,并且包含军队(其中包含许多单位)。

所以我认为我的模型不应该包含任何逻辑,只是获取和设置函数列表来检索数据,处理逻辑,问问题应该在Mapper内部完成......例如:

$villageMapper = new VillageMapper(); 
// Get village from database using mapper 
$village = $villageMapper->getVillage($id, new Village()); 

当我想确定说两个村庄相互攻击的结果时,在哪里做?我会做类似的事情吗?

$outcome = $villageMapper->determineAttackOutcome($village1, $village2); 

或者我会说......战术物体里面有一些逻辑吗?

$battle = new Battle(); 
// Add participants 
$battle->addAttacker($village1)->addDefender($village2); 
$outcome = $battle->performAttack(); 
// Save village changes cause of battle 
$villageMapper->save($battle->getAttacker()); 
$villageMapper->save($battle->getDefender()); 

我有一大堆的DBTABLE PHP文件,我想所有的数据库代码住在...所以我的问题是:如果我映射对象只有真正使用的东西像,获取并保存到数据库?

感谢,大教堂

+1

映射器充当数据库表和对象之间的接口。所以你的战斗应该可以在你的mapper之外进行。 – Config 2012-04-12 20:23:51

回答

5

有MVC的许多不同的解释,但是这是我的理解是:

模型:包含几乎所有与特定项目有关的逻辑。每一个必须建模的东西(在你的情况下,用户,villiages等)都有一个模型。该模型具有获取数据并将数据放入(i。即获得者和制定者)。该模型也做错误检查等,并确保没有冲突输入英寸

查看:没有任何逻辑。在一个Web应用程序中,这实际上只是表示将内容放在页面上的东西。在某些框架中,您为视图提供了一个模型(即ASP.NET MVC3),但在其他框架(如Savant3 for php)中,它可以提供任何东西。控制器通常会提供视图,但是如果视图被赋予一个模型,它只会从模型中读取并且不会写入该模型。

控制器:控制用户和模型之间的交互。当用户做某事时,控制器将其转换为模型必须做的事情。例如,如果你对节目“请将我的角色向北移动6个空间”说,控制器会说:“有什么东西跑到北面的6个空间吗?”如果它看到这个地方很清楚,它会告诉人物模型“向北移动6个空间”。这样做之后,它会将数据发送到视图,以显示作为结果显示的内容。控制器中实现的大多数实际逻辑应该是用户模型而不是模型模型。模型之间的交互可以通过单个模型中的方法或封装某种行为或交互的其他模型来处理。

因此,在您的实现:

我会做一个战斗的对象(这是一个模型),它的构造函数有两个村庄或任何战斗。它会有一个叫做execute或doBattle的方法或控制器会调用的某个方法,然后战斗对象将执行其逻辑来决定结果并更新战斗员的状态(即降低HP,给予经验等)。它会向控制器返回结果,以便控制器知道该做什么(即,如果控制器因为死亡而需要忘记模型,它会告诉它)。这个返回值也可能是发送给视图来说明战斗结果的东西。

您的一些模型(如用户,村庄等)将被保存在数据库中,因此模型会知道如何将自己映射到该数据库(或者它会与另一个知道如何映射它的图层进行对话),并且要注意更新数据库和东西的确切实现(控制器会调用实际的方法来“保存”,但模型将是唯一知道幕后发生的事情)。其他模型(如战斗)不需要存在于数据库中,因为它们只是逻辑封装了一些交互。

+0

我不同意你对控制器的描述。如果你对程序说'把我的角色移到北方6',那么控制器不应该检查任何东西,它应该把请求交给模型。然后,模型会执行所需的任何检查/移动操作,并将新位置报告给控制器。 – vascowhite 2012-04-13 13:37:20

1

有一个脂肪模式意味着然后几乎所有的逻辑模型中存在。

一些sugesstions ...

如果你正在做的领域驱动设计(http://en.wikipedia.org/wiki/Domain-driven_design)你的村庄对象可以是管理业务逻辑的聚合根那个村庄。

一场战斗也可能是一个由两个(或多个)村庄对象组成的聚合根,或者是一个服务,它接收两个村庄对象并返回一个“结果”对象。你也可以按照$ village-> attack($ anotherVillage)的方法做一些事情,这样可以返回一个战斗对象,然后你可以继续。

我建议以下领域驱动设计和库模式,当谈到创建和坚持这些业务对象http://msdn.microsoft.com/en-us/library/ff649690.aspx

1

Datamapper只能用于存储和检索数据库中的数据并将该数据映射到您的域对象(用户,村庄,军队,MapSquares)。

您可以将您的逻辑放入您的域对象中,但我喜欢使用服务层。

在你的控制你会做这样的事情:

function attackAction() { 
    $gameService->doVillageBattle($villageId1,$villageId2); 
} 

GameService会是什么样子:

doVillageBattle($villageId1,$villageId2) { 
    $village1 = villageService->getById($villageId1); 
    $village2 = villageService->getById($villageId2); 

    if ($village1->getStrength() > $village2->getStrength()) { 
     $village1->winBattle(); 
     $village2->looseBattle(); 
     $villageService->save($village1); 
     $villageService->save($village2); 
    } 

} 

最后VillageService将有:

function save($village) { 
    villageMapper->save($village); 
} 

所以控制器跟服务只有和服务彼此对话或与逻辑上与t相关的数据加载程序进行通信下摆。服务承载了大部分“业务逻辑”,并且独立于数据库。 Datamappers是独立于服务控制器的服务&。