It's All About The Layers 核心思想就是分层

As you may have noticed, a key to solid application design is simply separating responsibilities, or creating layers of responsibility. Controllers are responsible for receiving an HTTP request and calling the proper business layer classes. Your business / domain layer is your application. It contains the classes that retrieve data, validate data, process payments, send e-mail, and any other function of your application. In fact, your domain layer doesn't need to know about "the web" at all! The web is simply a transport mechanism to access your application, and knowledge of the web and HTTP need not go beyond the routing and controller layers. Good architecture can be challenging, but will yield large profits of sustainable, clear code.

你可能注意到,优化应用的设计结构的关键就是责任划分,或者说是创建不同的责任层次。控制器只负责接收和响应 HTTP 请求然后调用合适的业务逻辑层的类。你的业务逻辑/领域逻辑层才是你真正的程序。你的程序包含了读取数据,验证数据,执行支付,发送电子邮件,还有你程序里任何其他的功能。事实上你的领域逻辑层不需要知道任何关于“网络”的事情!网络仅仅是个访问你程序的传输机制,关于网络和 HTTP 请求的一切不应该超出路由和控制器层。做出好的设计的确很有挑战性,但好的设计也会带来可持续发展的清晰的好代码。

For example, instead of accessing the web request instance in a class, you could simply pass the web input from the controller. This simple change alone decouples your class from "the web", and the class can easily be tested without worrying about mocking a web request:

举个例子。与其在你业务逻辑类里面直接获取网络请求,不如你直接把网络请求从控制器传给你的业务逻辑类。这个简单的改动将你的业务逻辑类和“网络”分离开了,并且不必担心怎么去模拟网络请求,你的业务逻辑类就可以简单的测试了:

class BillingController extends BaseController{
    public function __construct(BillerInterface $biller)
    {
        $this->biller = $biller;
    }
    public function postCharge()
    {
        $this->biller->chargeAccount(Auth::user(), Input::get('amount'));
        return View::make('charge.success');
    }
}

Our chargeAccount method is now much easier to test, since we no longer have to use the Request or Input class inside of our BillingInterface implementation as we are simply passing the charged amount into the method as an integer.

现在 chargeAccount 方法更容易测试了。 我们把 Request 和 Input 从 BillingInterface 里提出来,然后在控制器里把方法需要的支付金额直接传过去。

Separation of responsibilities is one of the keys to writing maintainable applications. Always be asking if a given class knows more than it should. You should frequently ask yourself: "Should this class care about X?" If answer is "no", extract the logic into another class that can be injected as a dependency.

编写拥有高可维护性应用程序的关键之一,就是责任分割。要时常检查一个类是否管得太宽。你要常常问自己“这个类需不需要关心 XXX 呢?”如果答案是否定的,那么把这块逻辑抽出来放到另一个类里面,然后用依赖注入的方式进行处理。(译者注:依赖注入的不同方式还记得么?调用方法传参、构造函数传参、从 IoC 容器获取等等。)

Single Reason To Change

A helpful method of determining whether a class has too many responsibilities is to examine your reason for changing code within that class. For example, should we need to change code within a Biller implementation when tweaking our notification logic? Of course not. The Biller implementations are concerned with billing, and should only work with notification logic via a contract. Maintaining this mindset as you are working on your code will help you quickly identify areas of an application that can be improved.

如何判断一个类是否管得太宽,有一个有用的方法就是检查你为什么要改这块儿代码。举个例子:当我们想调整通知逻辑的时候,我们需要修改 Biller 的实现代码么?当然不需要,Biller 的实现仅仅需要考虑支付,它与通知逻辑应当仅通过约定来进行交互。使用这种思路过一遍代码,会让你很快找出应用中需要改进的地方。

results matching ""

    No results matching ""