我有一点设计问题。让我们说我有一个包含大量人的项目。我想允许用户使用他选择的信息将这些人导出到CSV
文件
例如,他可以选择Id,姓名,电话号码,根据他的选择我会创建文件
当然,有一种简单的方法就像if(idCheckBox.Checked) getId();
等
我正在寻找更好的东西。我不希望我想添加的每个新选项都需要更改UI
(例如新复选框)。
我想过从文件中读取可能的选项,但这只会解决UI
问题。如何在不使用所有这些值的情况下知道要获得哪些值#34;如果"再次?
答案 0 :(得分:0)
此任务不需要花哨的设计模式。但是我知道你已经确定了改变的理由(将来添加选项)。因此,您希望最大限度地减少要修改的类的数量。
您真正的问题是如何将
在以下示例中,CSV对象与它接收和解析的对象真正分离。为了实现这一点,我们编写了一个抽象而不是一个实现。这样我们甚至不会耦合到Person对象,但会欢迎任何实现AttributedObject接口的对象。这种依赖关系被注入我们的CSV解析器。
我在PHP中实现了这个,但想法是一样的。 C#是一种静态语言,因此获取属性会有一些变化。您可以使用某种ArrayAccess接口。
interface AttributedObject {
public function getAttribute($attribute);
}
class Person implements AttributedObject {
protected $firstName;
protected $lastName;
protected $age;
protected $IQ;
public function __construct($firstName, $lastName, $age, $IQ)
{
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->age = $age;
$this->IQ = $IQ;
}
public function getAttribute($attribute)
{
if(property_exists($this, $attribute)) {
return $this->$attribute;
}
throw new \Exception("Invalid attribute");
}
}
class CSV {
protected $attributedObject = null;
protected $attributesToDisplay = null;
protected $csvRepresentation = null;
protected $delimiter = null;
public function __construct(AttributedObject $attributedObject, array $attributesToDisplay, $delimiter = '|')
{
$this->attributedObject = $attributedObject;
$this->attributesToDisplay = $attributesToDisplay;
$this->delimiter = $delimiter;
$this->generateCSV();
}
protected function generateCSV()
{
$tempCSV = null;
foreach ($this->attributesToDisplay as $attribute) {
$tempCSV[] = $this->attributedObject->getAttribute($attribute);
}
$this->csvRepresentation = $tempCSV;
}
public function storeCSV()
{
$file = fopen("tmp.csv", "w");
fputcsv($file, $this->csvRepresentation, $this->delimiter);
}
}
$person1 = new Person('John', 'Doe', 30, 0);
$csv = new CSV($person1, array('firstName', 'age', 'IQ'));
$csv->storeCSV();
答案 1 :(得分:0)
您可以根据允许用户选择的字段以及所需的字段来构建字段映射集。可以从文件或数据库中读取此数据。您的导入/导出可以根据需要灵活调整。
这是一个可以想象的数据结构,可以保存导入/导出集的信息。
public class FieldDefinition
{
public FieldDataTypeEnum DataType { get; set; }
public string FieldName{get;set;}
public int MaxSize { get; set; }
public bool Required { get; set; }
public bool AllowNull { get; set; }
public int FieldIndex { get; set; }
public bool CompositeKey { get; set; }
}
public class BaseImportSet
{
private List<FieldDefinition> FieldDefinitions { get; set; }
protected virtual void PerformImportRecord(Fields selectedfields)
{
throw new ConfigurationException("Import set is not properly configured to import record.");
}
protected virtual void PerformExportRecord(Fields selectedfields)
{
throw new ConfigurationException("Export set is not properly configured to import record.");
}
public LoadFieldDefinitionsFromFile(string filename)
{
//Implement reading from file
}
}
public class UserImportSet : BaseImportSet
{
public override void PerformImportRecord(Fields selectedfields)
{
//read in data one record at a time based on a loop in base class
}
public override string PerformExportRecord(Fields selectedfields)
{
//read out data one record at a time based on a loop in base class
}
}