因此,我决定尝试使用相同的功能从头开始重新编码网站,但采用OOP格式.
我遇到的问题是选择课程,我理解OOP以及它应该如何工作,但似乎总是遇到麻烦.我不确定是否应该尝试为具有登录用户功能的用户类等类创建函数,或者用户类应该只是添加/更新/显示用户详细信息,并且系统中的登录部分会更好类?
目前我已经开始使用以下类和函数,但它们是否适合此类别?
<? class User { var $userId,$username,$userRole,$userEmail; function isLoggedIn(){ } function login($postusername,$postpassword) { } function increaseLoginCount(){ } function logout(){ } } ?>
然后我可以在page.PHP中使用类似下面的内容..(连接类未显示)
<? $db = new Connect; $db->connect(); $user = new User; if(!$user->isLoggedIn()) { echo "Please Log In."; if($_POST['user']) { $user->login($_POST['username'],$_POST['password']); } } else { if($_POST['logout']) { $user->logout(); exit; } echo $user->username." Logged In.<br />"; } ?>
但是,该网站将有页面显示游戏类别,我不知道displayGames()函数适合哪里,因为它不是一个游戏,所以不会进入’游戏’类?
I run an arcade site and over the past few years
想想你能够应付多少以及你正在处理什么.还要了解多年来您已经获得了有关运行街机网站的具体知识.您已经获得了所在地区的专业.永远不要低估自己的地位和资产,这是你经营的基础,你将引入变革.这包括您网站的用户群.
it’s had many features added,it’s got to the point where procedural programming just looks way too complicated and adding new features or making simple design modifications can be very tricky.
如果系统增长,它们会变得越来越复杂.这不仅仅是程序式编程,它是事实.当您现在运行该网站多年时,您就会知道事情的变化,特别是在用户与您的网站的接口方面.
Therefore I’ve decided to try and recode the site from the ground up with the same features but in an OOP format.
据说可以使用OOP技术制作可重复使用的软件,有(也可能不是)任何证据.
但是,商业软件开发中只有很少的例子,从头开始重写整个应用程序是成功的.很少.商业软件开发规则可能不适用于您的具体情况,所以只是说.
在重新编码网站之前请三思而后行.做很多工作只是为了实现同样的目标,这有点没用,可能令人失望.相反,可能更具体地看一下你当前的设计中哪一个引入了你想要改变的最大问题.
PHP可以混合使用过程和面向对象的样式,这在您拥有遗留代码时尤为有用(遗留代码的常见定义是没有自动化测试的代码).
The issue I have is picking the classes,
我试着改写一下:为什么写类?
I understand OOP and how it should work but always seem to have trouble getting started.
开始始终是最艰难的一步.你现在已准备好做出决定,但你无法展望未来.消除风险最大的部分,降低风险.你可能已经开始在这里提出一个问题,以获得一些反馈来作出决定,但这可能不会减轻负担并可能导致混淆.然而,接受教育往往是一件好事.
I am unsure whether I should be trying to make functions for classes such as a user class with log in user function or if the user class should just be to add/update/show user details and the log in part would be better in a system class?
这在很大程度上取决于应用程序的性质和用户的性质.可能大多数脚本只需要知道用户是具体的还是匿名的(匿名用户还没有登录),它的ID,名称或昵称.
应用程序应该将该用户提供给任何消费组件,因此每个命令/脚本不需要处理:a)获取用户信息和处理用户(如登录),b)验证组件是否对用户有效(访问控制) ).那应该放在其他地方,例如在application controllerPofEAA.
每个具有应用程序控制器对象的脚本/命令都可以请求用户并与用户进行交互.
然而,这只是从技术上讲.处理自己不确定的事实,处理这些信息.尝试更好地制定具体问题,列出解决问题的具体方法的优缺点,在开始编码之前再次远离具体代码.然后比较利弊.尽量使事情变得更简单,更简单.
At the moment I’ve started with the following class and functions but do they fit in this category**?**
你的代码很简单,所以很难说出来 – 特别是因为我不知道你的街机网站是什么(以及你所写的类别).它可能仍然适用于一个例子.您可以在课堂上看到的是,您将所有内容紧密地整合在一起.
例如,您从数据库开始.这很常见,因为DB是任何应用程序的核心组件.应用程序需要DB才能运行.但是,您希望保持松散耦合,以便所有命令都可以与其他数据库或新的用户对象一起运行,该用户对象甚至与应用程序的其他数据对象之外的其他数据库连接.
$application->getDB();
由于用户是每个应用程序中的中心主题,因此它应该具有非常简单的界面.有关身份验证,检索用户属性等的所有荣耀细节都应委托给另一个类/组件,以便您可以更改用户存储的实现以及它们的身份验证方式:
/** * @package command.modules.games */ function ListGamesCommand(Request $request,Response $response) { $application = $request->getApplication(); $user = $application->getSession()->getUser(); $games = $application->getModels()->build('games'); $games = $games->findByUser($user); $response->setProp('games',$games); }
如此示例所示,您可以在需要时添加功能.例如.只要您的应用程序不需要实际登录用户,为什么要关心它现在的编写方式?
创建一个为应用程序对象生成用户的工厂 – 无论现在还是将来需要它(参见The Clean Code Talks — Inheritance,Polymorphism,& Testing中的两堆对象).如果您需要身份验证,请将其添加到会话对象或用户对象界面.
身份验证本身无论如何都将在它自己的类中实现,即Authenticator.因此,您也可以稍后通过将身份验证调用从会话移动到用户或其他任何内容来查看您的接口.只有一小部分命令需要处理这些特定任务,并且由于所有新代码都在自动测试中,因为您希望重写并从OOP中受益,因此您已确保覆盖所有位置并进行适当的重新分解.
访问请求变量也是如此.如果你想利用OOP的好处 – 它与间接高度相关(并且每个间接层都需要付出代价) – 首先应该让你的基类对特定数据进行操作而不是对任何数据进行操作(如全局和超全局,我在你的示例代码中看到了$_POST).
因此,启用新代码以处理请求并提供响应(输入 – 处理 – 输出):
$request = new Request($_SERVER,$_GET,$_POST,$_COOKIE,$_FILES,$_ENV); $response = new Response;
例子来自BankAccount – Sample application used for PHPUnit training
现在,这下面的所有内容都可以在Request和Response对象上运行 – 处理输入并将其转换为输出. domain命令(执行该操作的脚本/命令)不再需要关心从HTTP请求中提取输入,例如使用$_POST或$_GET它们可以直接从请求中获取 – 或者如果您编写了一个类它自己的命令 – 这可以更加量身定制.并且一些命令可以对它们自己的请求和响应进行操作.
I’ve decided to try and recode the site from the ground up with the same features but in an OOP format.
我已经写过,这样做可能毫无结果.获得OOP代码的好处意味着下次更改代码时,您仍然可以重用组件.随着软件的不断变化,现在这一次已经是下一次了.所以你想重新使用现有的代码.我假设您现有代码的一部分是输出逻辑.因此,现有输出逻辑需要与上面的示例性请求和响应接口.
我打赌你喜欢网站.你喜欢让它们工作,看起来很棒.多年来你已经建立了你的网站,甚至不是你希望的一切,你不想放弃它.因此,对于重写而言,至关重要的是你不要破坏所有东西,但是你可以保留它从现在到未来的工作形式(参见Preserve a Working Application; last point of the list).
在webapps中,视图是如此重要的一部分.如果您放松了视图,您的网站将失去其身份.如果您对其进行了太多改动,那么您的网站将会让那些习惯使用它的用户感到沮丧.
如果你打破它,
>你会注意到吗?
>你能解决吗?
另一方面,您希望您的应用程序代码(功能,功能)不再与它紧密绑定,以便在重写代码时获益.当你想重写你的应用程序时,让我们来看看:
.---------. .-------------. | website | ---> [interface in ] ---> | application | | user | <--- [interface out] <--- | | `---------´ `-------------´
如此架构所示,为了使您的应用程序更加独立于交互的外观(可以是网站,(智能手机)GUI或票务系统),应用程序代码应该是可替换的.您不希望编写逻辑来获取用户游戏,例如新应用程序代码中的每种类型的用户界面,但是您在旧的应用程序代码中进行了编写.
以User对象为例.它如何进行身份验证以及存储位置不应该是您的新应用程序命令代码所关注的内容.如果命令需要它就在那里.不是全局的,而是具体的,如果命令要求它.
其中 – 注册和丢失密码程序是您现有应用程序的一部分并继续存在.
因此,您可能会从HTTP请求和HTTP响应的接口开始.该视图启动了Interface Out.您通过该接口为视图分配/传递所有需要的数据,您的应用程序不再知道视图.您不需要处理新应用程序代码中的任何CSS,Javascript或HTML代码.这只是输出顶部的糖.您的应用程序也应通过纯文本控制台/ telnet或远程XMLRPC服务,AJAX端点 – 无论如何接口.
所以你可以概括一下你的视图代码并为它注入变量.编写视图层可以像包含PHP文件一样简单.它运行在其范围内可用的变量.它可以使用其范围内可用的“辅助”函数(模板宏).它可以使用视图模型对象.甚至可以为视图编写自己的语言(模板语言,域特定语言(DSL)).
但是,只有在创建允许应用程序代码执行此操作的接口时,才有可能实现此目的.
所以你现在要做的就是将你的应用程序中的HTTP / HTML / CSS / JS移到它自己的适配器上.该适配器能够制定通用命令,该命令可以通过接口传递给任何应用程序.
应用程序只会注意执行命令并通过接口输出它的响应.所以你现在有两个域:你的应用程序和网站.
您可以开始创建这两个新域,然后为遗留代码和新代码提供一个接口.
您还有“两个”应用程序彼此相邻.它们最终与您的数据库绑定在一起(在自己的代码中不可见),这会照顾您站点的数据.这就是数据库的用途.将数据与代码分开,以便随着时间的推移更改代码.
祝好运!我希望阅读本文将为您的具体案例提供一些选择.另请注意,您不要将控制器转换为数据库的另一个外观.通过使用轻量级HTTP抽象和视图层,您可能获得了最好的好处(不知道具体的最大问题),因为您的应用程序可能仅适用于网站.
因为在HTTP / PHP中:
[Interface In] Plain Text HTTP request [Application] Free to go [Interface Out] Plain Text HTTP response
另外,不使用胖模型的好处是可以快速,顺序地访问数据,例如:如果您不需要立即传递输出(缓冲,一个块),您可以获得将输出流式传输到服务器的好处.
您应该确定哪些部分对于您的应用重构是重要的,而不是OOP.与程序一样,OOP也需要做得好.如果您今天通过编写过程代码遇到问题,OOP代码可能无法解决您的问题.编写更好的过程代码的需要可能就是它.只是说,重构一个应用程序并不容易,你应该首先确定实际问题.
>如果你打破它,你会注意到吗?
>如果你打破它,你能解决它吗?
关键部分是你可以注意到并且你手头有一切可以解决问题.
让您的网站受到测试,这样您就可以说在这里或那里更改代码确实有效.能够将任何变化都改回来,如果它发光它不起作用(更好).
这样就可以轻松决定是否有新功能.只要您不需要引入新功能,就无需更改编写功能的方法.在此之前,您无法计划新功能.
因此,在重新编写应用程序之前,最好三思.如上所述,这可能会导致项目失败.
另见:How to implement MVC style on my PHP/SQL/HTML/CSS code?SO Q&A