1

基于在 stackoverflow 上得到的一些好的建议,我需要更多的指导。有人告诉我,关注点分离对于保持代码整洁和模块化很重要,我发现确实如此。

我的问题是:根据我对 SOC 的了解,我开发了 2 个类。供应商类和 CSV 类。供应商仅从数据库中检索有关我的不同供应商的数据。Csv 类从正在导入的 csv 文件中检索数据,我需要解析它的所有信息,最终目标是将数据插入到我的供应商表中。为了实现将 csv 数据插入数据库的目标,我需要使用这两个类中的方法。我是否创建了一个名为 ImportSuppliersCsv 之类的第三类,还是将导入函数创建为 Suppliers 类的方法更有意义?

缩短以节省空间,我的课程是这样的:

class Suppliers
{


    public $db;
    public $inv;
    public $table;


    public function __construct (PDO $db)
    {

        $this->db = $db;
        $this->inv = 'lightsnh_inventory';
        $this->table = 'suppliers';

    }


    public function getSuppliers() 
    {               

        $sql = 'SELECT * FROM `'.$this->inv.'`.`'.$this->table.'`';
        $statement = $this->db->query($sql);
        $result = $statement->fetchAll(PDO::FETCH_ASSOC);

        return $result;

    }


    public function getActiveSuppliers() 
    {               

        $suppliers = $this->getSuppliers();     
        $active = array();      
        foreach($suppliers as $supplier) {

            if($supplier['exclude'] == 0)           
                    $active[] = $supplier;

        }

        return $active;

    }


    public function getDistributors() 
    {               

        $suppliers = $this->getSuppliers();     
        $distributors = array();        
        foreach($suppliers as $supplier) {

            if($supplier['type'] == 1)          
                    $distributors[] = $supplier;

        }

        return $distributors;

    }



    class Csv
    {


        public $form;


        public function __construct($form_name)
        {

            $this->form = $form_name;

        }


        public function getFile()
        {

            if(isset($_POST[$this->form.'-upload-submit'])) {

                return $_FILES[$this->form.'-file'];

            }

        }


        public function getName()
        {

            $file = $this->getFile();
            return $file['name'];

        }


        public function getExtension()
        {

            return end(explode('.',$this->getName()));

        }


        public function getType()
        {

            $file = $this->getFile();
            return $file['type'];

        }   etc.....
4

2 回答 2

0

两者都不。OOP/SoC/DI 等不是目的,它们是一种手段。SoC 的目的是使维护更容易的模块化架构,尽管分离关注点总是通过模糊问题来扩大问题。我发现在 PHP 中提出一个好的设计的最好方法是首先让它工作,然后重构。您也可以先在您的想象中执行此操作以节省一些时间。以您认为最好的方式组织它。毕竟,这个想法是为了让要维护代码的人能够轻松找到自己的方式,因为他们是以这种方式组织代码的。简而言之,谨防过度设计。

在你的例子中,如果它只在一个地方使用,我不会费心去做一类东西。举个例子:通常一个可以将 CSV 记录导入数据库的应用程序,也有一个表单来编辑这些行,所以我假设 Suppliers 类中有一个“保存”功能,因为它已经抽象了查询(糟糕- 没有缓存、没有 WHERE 子句、SQL 注入等)。现在导入 CSV 文件的问题是将数据有序地呈现给这个“保存”功能的问题。

现在,将 CSV 文件导入数据库的基本代码本身就是这样简单:

$data = array_map( 'str_getcsv', explode("\n", file_get_contents( $filename ) ) );
$columns = array_shift( $data );
$sth = $db->prepareStatement( "INSERT INTO suppliers( " . implode( ',', $columns )
  . ") VALUES ( " . substr(str_repeat(",?",count($columns)),1) . ")"
);
foreach ( $data as $line )
  $sth->execute( $line );

通常它不是那么理想——但这本质上是核心功能。它只有 4 个语句,四个关注点:解析 CSV、映射字段、更新数据库和效率/一致性(使用准备好的语句)。

OOP 仍然依赖于函数式编程——按功能组织。以上内容可以保留为脚本,由 cron 作业或网页调用。它可以放在函数“import_csv”中,供这些任务重用。但是把它放在一个班级里是矫枉过正的。SoC 还使用外观或接口。函数就是这样,如果需要,可以很容易地分组到一个类中。您只需要一个函数 import_csv( $filename, $profile )。$profile 将指示表(或表)、列映射等。通过将它们分开,您可以制作通用的 CSV 到 DB 映射编辑器 - 或者至少支持仅通过更改配置将任何 CSV 文件导入任何表。如果您对所有内容进行分类,您最终将为您必须导入的每个 CSV 文件编写一个类。

想象一下,不管数据如何,都是一个通用的导入器。专注于功能,因为这就是代码。这是一种更好的方法,因为您的代码将不依赖于数据库结构 - 您已经抽象了它(通过使用公共接口扩展 Table 基类,以便您可以 $table->save())。您不会抽象 CSV(这是不值得的,如第一行代码所示),而是映射。

这不是您期望的答案,但我确定您不希望答案是您给出的答案,因为您将其作为问题提出。

于 2015-01-15T02:42:17.443 回答
-1

您不需要新类即可从 CSV 插入新供应商。您可以简单地添加一个新方法并将一个 Csv 对象传递给它。这样,所有与供应商相关的活动都将封装在一个类中。

或者,如果您打算拥有其他信息源,除了 CSV,您可以让供应商方法接受解析的信息,而不是 CSV 对象。

于 2013-04-09T07:14:15.423 回答