Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何更正我的设计以避免循环依赖_Php_Laravel_Architecture_Solid Principles - Fatal编程技术网

Php 如何更正我的设计以避免循环依赖

Php 如何更正我的设计以避免循环依赖,php,laravel,architecture,solid-principles,Php,Laravel,Architecture,Solid Principles,我绞尽脑汁想找到一个解决方案,但我仍然不能,我正在寻找一个设计副解决方案,而不是一个黑客来解决这个问题 我有以下课程 class CourseService{ public function getCourse($courceId){ $course = $this->courseRepo->getCourse($courseId); $restrictions = $this->invoiceService->getRes

我绞尽脑汁想找到一个解决方案,但我仍然不能,我正在寻找一个设计副解决方案,而不是一个黑客来解决这个问题

我有以下课程

class CourseService{

     public function getCourse($courceId){
         $course = $this->courseRepo->getCourse($courseId);
         $restrictions = $this->invoiceService->getRestrictions($course->courseid);
         $course->restrictions = [];
         if($restrictions != null){
           $course->restrictions = $restrictions;
         }
     }
}
  • 现在,这个课程服务被注入到
    StudentService
    的构造函数中,因为当学生需要注册到一个学校时,我在那里使用这个课程服务
  • 您还可以看到,我使用
    CourseRepo
    来获取课程对象,然后
    InvoiceService
    来说明哪些字段被限制更新,基本上
    restrictions
    属性提供了一个字符串数组,定义了哪些字段不允许编辑,我希望UI开发人员使用它来禁用这些字段,我必须注入
    InvoiceService
    ,因为需要对从
    invoicesrepo
    获取的原始数据库记录进行一些处理,所以invoicesrepo被封装在InvoiceService中
  • 现在让我们看看InvoiceService

    Class InvoiceService{
    
        public function getAmountToPay($courseid, $studentid){
             //now I need to inject StduentService inorder to get student info which needed for the calculation
        }
    }
    
  • 但是我不能在这里注入StudentService,因为
    StudentService
    ->
    CourceService
    ->
    InvoiceService
  • 我看到的选择和后果
  • 我看到的一个选择是从
    CourseService
    中去掉
    InvoiceService
    ,在调用
    getCourse()
    的地方使用
    InvoiceService
    ,然后修改结果,但问题是,
    CourseService
    主要用于控制器,接下来的事情是getCourse()从许多控制器和服务中调用,并期望有限制,因此,如果我想摆脱
    InvoiceService
    ,那么我将有许多地方添加删除行,并且它包含代码重复

  • 我可以将getAmountToPay()移动到学生服务,但该服务已经完成了许多与学生相关的任务,我很乐意将发票部分提取到另一个服务,这样当我需要检查发票上的错误时,我就有了一个清晰的位置


  • 我会将您的发票服务更改为不依赖于学生服务。将您需要的内容传递到invoiceService。如何处理这些学生详细信息的逻辑可以保留在invoiceService中,但内容可以传入。

    学生服务:

    首先,您必须看到(实际上是要确定)学生服务使用的是发票服务,而不是对等服务。当我注册成为历史系学生时,我首先去注册/学生办公室。他们打电话给财务/发票办公室询问我该付多少钱。财务办公室检查数据库并返回关于我要支付的金额的响应

    课程服务:

    …时光流逝。现在我是一名学生。我不需要再去登记处了。如果我必须了解我的课程,我会去秘书处/课程服务处。他们会给我所有我需要的关于课程的信息。但是,如果我想参观一些特殊的考古学课程,其中必须支付一些费用,课程服务将致电财务/发票服务为我询问。反过来,他们将返回信息。如果课程服务想要了解我应该具备的一些财务限制,同样适用:他们调用财务/发票服务

    发票服务-学生服务、发票服务-课程服务:

    现在,如果发票服务需要关于学生或课程的信息,该怎么办?它应该叫学生服务,还是叫课程服务?答案是否。发票服务应接收学生id、课程id、域对象学生或域对象课程作为构造函数/方法依赖项,但不接收相应的服务。它将自己获取所需的信息。更重要的是,发票服务应该使用其特定的发票/财务表,而不是课程表或学生详细信息表(id除外)

    结论:

    • 招收学生是学生服务处的工作。尽管 CourseService可以协助注册过程
    • StudentService通过调用 发票服务。我知道您不想使用
      getAmountToPay()
      在StudentService内部,但这是一个自然的工作流。你可能会想 将其他许多事情分开,学生服务就是其中之一 负责,为他人服务
    • CourseService负责查找课程,以及 课程限制,它为此调用InvoiceService。所以 课程服务将由发票服务协助
    在下面,我向您传递了我的愿景的PHP版本。我重命名了一些函数,为的是给你一个更好的视角

    祝你好运

    附言:我希望我的理解是正确的,“发票服务”的意思是“财务部门”。对不起,我不是以英语为母语的人,所以我不知道所有的意思

    <?php
    
    class StudentService {
    
        protected $courseService;
        protected $invoiceService;
    
        /**
         * Even if the course service uses the invoice service,
         * doesn't mean that the student service shouldn't use it too.
         * 
         * @param CourseService $courseService
         * @param InvoiceService $invoiceService
         */
        public function __construct(CourseService $courseService, InvoiceService $invoiceService) {
            $this->courseService = $courseService;
            $this->invoiceService = $invoiceService;
        }
    
        /**
         * Enroll a student to a course.
         * 
         * @param integer $studentId
         * @param integer $courseId
         * @return bool Enrolled or not.
         */
        public function enrollToCourse($studentId, $courseId) {
            //... Use here the CourseService too - for what you said regarding the enrollment.
            $enrolled = $this->studentRepo->enrollToCourse($studentId, $courseId);
            return $enrolled;
        }
    
        /**
         * Get the amount to be payed by a student on the enrollment moment.
         * 
         * @param integer $studentId
         * @param integer $courseid
         * @return integer Amount to be payed.
         */
        public function getAmountToPayOnEnrollment($studentId, $courseid) {
            $amount = $this->invoiceService->getAmountToPayOnEnrollment($studentId, $courseid);
            return $amount;
        }
    
    }
    
    class CourseService {
    
        protected $invoiceService;
    
        /**
         * Invoice service is used to get the (financial) restrictions for a course.
         * 
         * @param InvoiceService $invoiceService
         */
        public function __construct(InvoiceService $invoiceService) {
            $this->invoiceService = $invoiceService;
        }
    
        /**
         * Get a course and its corresponding (financial) restrictions list.
         *  
         * @param integer $courseId
         * @return Course Course domain object.
         */
        public function getCourse($courseId) {
            $course = $this->courseRepo->getCourse($courseId);
            $course->restrictions = $this->getRestrictionsForCourse($course->courseId);
            return $course;
        }
    
        /**
         * Get the (financial) restrictions for a specified course.
         * 
         * @param integer $courseId
         * @return array Restrictions list.
         */
        public function getRestrictionsForCourse($courseId) {
            $restrictions = $this->invoiceService->getRestrictionsForCourse($courseId);
            return $restrictions;
        }
    
    }
    
    Class InvoiceService {
    
        /**
         * No student service needed!
         */
        public function __construct() {
            //...
        }
    
        /**
         * Again, no student service needed: the invoice service
         * fetches by itself the needed infos from the database.
         * 
         * Get the amount to be payed by a student on the enrollment moment.
         * 
         * @param integer $studentId
         * @param integer $courseid
         * @return integer Amount to be payed.
         */
        public function getAmountToPayOnEnrollment($studentId, $courseid) {
            $amount = $this->invoiceRepo->getAmountToPayOnEnrollment($studentId, $courseid);
            return $amount;
        }
    
        /**
         * Get the (financial) restrictions for a course.
         * 
         * @param integer $studentId
         * @param integer $courseid
         * @return array Restrictions list.
         */
        public function getRestrictionsForCourse($courseid) {
            $restrictions = $this->invoiceRepo->getRestrictionsForCourse($courseid);
            return isset($restrictions) ? $restrictions : [];
        }
    
        /*
         * Quote: "Some processing to do to the raw 
         * db records that are fetched from the InvoiceRepo".
         */
        //...
    }
    

    顺便问一下,您是否看到您在函数中接受的veriable有输入错误?我跟你打赌,这只是一个抽象的代码,只是为了解释我的情况。