gpt4 book ai didi

PHP OOP : interface vs. 非接口(interface)方法 - 示例

转载 作者:行者123 更新时间:2023-12-04 20:51:56 25 4
gpt4 key购买 nike

人们可以使用不同的工具完成相同的事情。
我在下面的例子中也是如此。

一个展示了接口(interface)/多态性的使用(来源:nettuts - 我认为)。另一个简单的类交互(我的) - 它也显示了一些多态性(通过 call_tool())。

你能告诉我,你认为哪种方式更好。

哪个更安全、更稳定、防篡改、 future 证明(afa 代码开发)。

请仔细检查两者中使用的范围/可见性。

您的一般建议,这是最佳编码实践。

界面:

类 poly_base_Article {

公开 $title;
公共(public) $author;
公开 $date;
公共(public) $category;

公共(public)函数 __construct($title, $author, $date, $category = 0, $type = 'json') {
$this->title = $title;
$this->author = $author;
$this->date = $date;
$this->category = $category;

$this->type = $type;
}

公共(public)函数 call_tool() {
$class = 'poly_writer_' 。 $this->type 。 '作家';
如果(class_exists($class)){
返回新的 $class;
} 别的 {
throw new Exception("不支持的格式:". $this->type);
}
}

公共(public)函数写(poly_writer_Writer $writer){
返回 $writer->write($this);
}

}

接口(interface) poly_writer_Writer {

公共(public)函数写(poly_base_Article $obj);
}

类 poly_writer_xmlWriter 实现 poly_writer_Writer {

公共(public)函数写(poly_base_Article $obj){
$ret = '';
$ret .= '' 。 $obj->title 。 '';
$ret .= '' 。 $obj->author 。 '';
$ret .= '' 。 $obj->日期。 '';
$ret .= '' 。 $obj->category 。 '';
$ret .= '';
返回 $ret;
}

}

类 poly_writer_jsonWriter 实现 poly_writer_Writer {

公共(public)函数写(poly_base_Article $obj){
$array = array('article' => $obj);
返回 json_encode($array);
}

}

$article = new poly_base_Article('Polymorphism', 'Steve', time(), 0, $_GET['format']);
echo $article->write($article->call_tool());

非接口(interface)

类 npoly_base_Article {

公开 $title;
公共(public) $author;
公开 $date;
公共(public) $category;

公共(public)函数 __construct($title, $author, $date, $category = 0, $type = 'json') {
$this->title = $title;
$this->author = $author;
$this->date = $date;
$this->category = $category;
$this->type = $type;//编码类型 - 默认:json
}

公共(public)函数 call_tool() {
//如果存在则调用工具函数
$class = 'npoly_writer_' 。 $this->type 。 '作家';
如果(class_exists($class)){
$cls = 新 $class;
返回 $cls->write($this);
} 别的 {
throw new Exception("不支持的格式:". $this->type);
}
}

}

类 npoly_writer_jsonWriter {

公共(public)函数写(npoly_base_Article $obj){
$array = array('article' => $obj);
返回 json_encode($array);
}

}

类 npoly_writer_xmlWriter {

公共(public)函数写(poly_base_Article $obj){
$ret = '';
$ret .= '' 。 $obj->title 。 '';
$ret .= '' 。 $obj->author 。 '';
$ret .= '' 。 $obj->日期。 '';
$ret .= '' 。 $obj->category 。 '';
$ret .= '';
返回 $ret;
}

}

$article = new npoly_base_Article('nPolymorphism', 'Steve', time(), 0, $_GET['format']);
echo$article->call_tool();

MikeSW 代码(如果我做对了)

类 poly_base_Article {

私有(private) $title;
私有(private) $author;
私有(private) $date;
私有(private) $category;

公共(public)函数 __construct($title, $author, $date, $category = 0) {
$this->title = $title;
$this->author = $author;
$this->date = $date;
$this->category = $category;
}

公共(public)函数 setTitle($title) {
返回 $this->title = $title;
}

公共(public)函数 getTitle() {
返回 $this->title;
}

公共(public)函数 getAuthor() {
返回 $this->author;
}

公共(public)函数 getDate() {
返回 $this->date;
}

公共(public)函数 getCategory() {
返回 $this->category;
}

}

接口(interface) poly_writer_Writer {

公共(public)函数写(poly_base_Article $obj);
}

类 poly_writer_xmlWriter 实现 poly_writer_Writer {

公共(public)函数写(poly_base_Article $obj){

$ret = '';
$ret .= '' 。 $obj->getTitle() 。 '';
$ret .= '' 。 $obj->getAuthor() 。 '';
$ret .= '' 。 $obj->getDate() 。 '';
$ret .= '' 。 $obj->getCategory() 。 '';
$ret .= '';
返回 $ret;
}

}

类 poly_writer_jsonWriter 实现 poly_writer_Writer {

公共(public)函数写(poly_base_Article $obj){
//数组替换
//$obj_array = array('title' => $obj->getTitle(), 'author' => $obj->getAuthor(), 'date' => $obj->getDate(), 'category' = > $obj->getCategory());
//$array = array('article' => $obj_array);

$array = array('article' => $obj);//$obj 到达时为空
返回 json_encode($array);
}

}

类作家工厂{

公共(public)静态函数 GetWriter($type='json') {
开关($type){
案例'json':
case 'xml': $class = 'poly_writer_' 。 $类型。 '作家';
返回新的 $class;
休息;
默认值:throw new Exception("不支持的格式:". $type);
}
}

}

$article = new poly_base_Article('nPolymorphism', 'Steve', time(), 0);
$writer=WriterFactory::GetWriter($_GET['format']);

echo $writer->write($article);

最佳答案

咳咳,无论什么版本,你的方法都有一些缺陷。首先, poly_base_Article 暴露了破坏封装的字段,并且有点违背了使用 OOP 的初衷。

接下来,您可以通过 $_GET 参数在那里进行良好的注入(inject)。正确的上课方式应该是这样的

 class poly_base_Article {

private $title;
private $author;
private $date;
private $category;

public function __construct($title, $author, $date, $category = 0) {
$this->title = $title;
$this->author = $author;
$this->date = $date;
$this->category = $category;

}

public function getTitle() { return $this->title;}
//...other getters defined here...

public function AsArray()
{
return (array) $this;
}

//this could be removed
public function write(poly_writer_Writer $writer) {
return $writer->write($this);
}
}

不过似乎不需要 write 方法,您只需告诉作者直接写入对象即可。

*call_tool* 方法应该属于服务或作为工厂方法来创建 poly_writer_Writer 的实例(顺便说一句,你应该将类和接口(interface)的命名更改为更自然的东西),像这样
class WriterFactory
{
public static function GetWriter($type='json')
{
switch($type)
{
case 'json'
case 'xml': $class= 'poly_writer_' . $type . 'Writer';
return new $class;
break;
default: throw new Exception("unsupported format: " . $type);
}
}
}


$article = new poly_base_Article('nPolymorphism', 'Steve', time(), 0);
$writer=WriterFactory::GetWriter(, $_GET['format']);
echo $writer->write($article);

Which is safer, more stable, tamper resistant, future proof (afa code development is concerned).



这仅取决于开发人员的技能和纪律。在这种特殊情况下,我编写的代码更安全、防篡改和面向 future :P

更新
确实,我忘记在 poly_base_Article 中放置 getter,我现在已经添加了它们。既然你在做序列化,文章不应该知道它,因为这不是他的责任(它是基础设施层的一部分)所以根本不需要写方法,但这是一个特定的情况(在一切取决于在上下文中)。

WriterFactory 基本上是工厂模式,它创建一个 writer 的实例并返回一个抽象 - 这就是接口(interface)有用的多态性。这种方法使得添加接口(interface)的新实现和防止代码注入(inject)变得非常容易。开关是检查是否只允许 $type 的有效值。您可能会在其他地方验证 $type ,但这是唯一应该处理与创建作家相关的所有事情的地方。即使您想在它之外进行验证,您只需在 WriterFactory 中创建一个静态方法,该方法将返回 true/false 并使用 than。

关于接口(interface)是一种时尚......使用接口(interface)是应该如何完成 OOP。针对抽象进行编程是最佳实践,并且接口(interface)是“最佳”抽象。坦率地说:如果接口(interface)是一种时尚,那么 OOP 就是一种时尚。

关于你的第二个例子,也是第一个,创建作者的方法首先不应该存在,因为它将作者的创建与文章相结合,而这两个几乎没有共同之处。这是对 SRP(单一职责原则)的破坏。

在这种特殊情况下,一旦您在单独的类中执行创建工厂,那么您几乎不关心接口(interface),但是因为这里的用法非常简单并且您使用的是 PHP 或松散类型语言。如果您将编写器作为依赖项传递,那么它将有助于传递接口(interface)而不是实际实现(就像您在第一个示例中所做的那样)。了解您所传递的类型非常有帮助。

同样在像 C# 这样的语言中,你会有一个返回类型,然后,作为一个最佳用法,你将它作为接口(interface)类型返回(C# 支持动态类型,它的行为有点像在 PHP 中,所以你可以返回动态而不是关心,但这会带来性能损失,如果返回的类型没有调用方法,它将抛出异常)

关于PHP OOP : interface vs. 非接口(interface)方法 - 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9604993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com