里氏替换原则:对子类型附加功能的混淆

问题描述 投票:0回答:1

早些时候,我正在学习 SOLID 原则,并尝试运用这些原则来获得更简洁、可维护的代码。

我正在使用 flutter 开发一个社交应用程序,当然有帖子需要发布。假设有两种类型的帖子

仅包含文字的帖子:

Post

包含图像和文本的帖子:

ImagePost

以下代码只是演示问题的示例:

class Post{
  
  String text;
  Post(this.text);
}

class ImagePost extends Post{

  String image;
  ImagePost(this.image, super.text);
}

void printy(Post p){ // p can be a Post or ImagePost
  
  print(p.text);

// for now, it's conformation to LSP

  if(p.runtimeType == ImagePost){
  print(p.image ); // error: cause Post (p) doesn't contain image field
}
}

void main() {
  Post post = Post('hi there');
  ImagePost imagePost = ImagePost('dumy link' , 'welcome');
  printy(imagePost);
} 

上述代码应符合里氏替换原则:“子类型必须可替换其基类型”。

但是,

image
里面有一个额外的功能(实际上它是一个属性)
ImagePost
,我需要在客户端方法
printy
中访问它,但我不能,因为
Post p
参数不包含图像。

我已经解决了这个问题,但在基类中定义了

printy method
并在子类中覆盖了它,

注意:这只是一个例子,实际项目中没有

printy
方法,它是一个
postBuilder method
,如果帖子是
ImagePost
,则需要访问图像以将其渲染在屏幕上。

问题简而言之:如果帖子是

image
,我需要访问 
printy
 客户端内的 
image post

属性

任何建议,谢谢。

flutter dart software-design solid-principles solid
1个回答
0
投票

您可以按照

polymorphism
和方法
overriding
。您可以在基类
Post
中创建一个方法,然后在
ImagePost
子类中重写它,而不是直接在 printy 方法中访问图像属性。

class Post {
  String text;

  Post(this.text);

  
  void printContent() {
    print(text);
  }
}

class ImagePost extends Post {
  String image;

  ImagePost(this.image, String text) : super(text);

  
  @override
  void printContent() {
    super.printContent(); 
    print(image); 
  }
}

void printy(Post p) {
  p.printContent();
}

void main() {
  Post post = Post('Aizan Sagheer');
  ImagePost imagePost = ImagePost('Any image link', 'Text');
  printy(post);
  printy(imagePost);
}

通过这种方式,您可以通过为基本类型提供可替换的行为来遵循 LSP。

© www.soinside.com 2019 - 2024. All rights reserved.