关键词:
【中文标题】我需要更改哪些内容才能正确实施 SOLID 设计?【英文标题】:What do I need to change to implement SOLID design correctly? 【发布时间】:2019-10-20 11:09:02 【问题描述】:我正在尝试学习 SOLID 设计,但我认为我犯了一个错误。我认为IItem
接口在我的Player
类中不遵循Liskov 替换原则,但是我不知道如何解决这个问题。如果我从 IItem 添加一个新的界面绘图,我将不得不更改 Player 的方法以添加一个案例来处理它。
我希望 Player 类只需要一种装备方法,因此需要帮助了解我做错了什么以及如何正确做。
我的界面的简化版:
interface IItem
string Name get; set;
int Value get; set;
Quality Quality get; set;
EquipmentType Type get; set;
interface IWeapon : IItem
interface IArmour : IItem
int Defence get; set;
Slot Slot get; set;
消费类 Player 类:
class Player
private Dictionary<Slot, IArmour> armour = new Dictionary<Slot, IArmour>();
private IWeapon weapon;
public bool Equip(IItem item)
switch (item.Type)
case EquipmentType.Armour:
var armour = item as IArmour;
if (this.armour.ContainsKey(armour.Slot))
return false;
this.armour.Add(armour.Slot, armour);
return true;
case EquipmentType.Weapon:
var weapon = item as IWeapon;
throw new NotImplementedException();
default:
return false;
上下文枚举:
enum Slot
Head = 0,
Soulders = 1,
Gloves = 2,
Neck = 3,
RRing = 4,
LRing = 5,
Torso = 6,
Legs = 7,
Boots = 8,
Bracers = 9,
Belt = 10,
enum EquipmentType
Armour = 0,
Weapon = 1
【问题讨论】:
是什么让你认为你在这里破坏了 LSP? @canton7 如果我以后从 IItem 添加一个新的派生接口,我将不得不更改播放器,据我了解这意味着它是不可替代的? 这里看起来更像是打开/关闭违规(SOLID 的“O”),而不是 Liskov 替换问题。如果您需要进行更改,则意味着您的代码没有关闭进行修改。 @Corentin Pane,好点子!你能给我什么建议让我回到正轨吗?我还在努力学习:) 如果你有一个派生自例如的类,你会破坏 LSP。IArmor
(我们称它为Shield
),如果您使用IArmor
引用它,则该类的行为与使用Shield
引用它时的行为不同。如果有的话,这违反了打开/关闭原则,因为如果您添加另一种类型的设备,您需要修改您的 Player
类以正确处理它(以及使用 EquipmentType
的所有其他地方)。但是我不会在这里担心 - 如果您添加一种新型设备,您的 Player
很可能需要一些升级来应对
【参考方案1】:
Liskov 替换原则 通常与您如何定义类有关。如果您编写一个派生自其他类(或实现某个接口)的类,则想法是有人应该能够使用您的类,就好像它是该父类的实例一样。您的子类可能具有父类没有的其他行为(当然,将您的类当作父类的实例使用的人将无法访问它),但是所有行为父类在子类中应该保持原样。
在您的示例中,这可能意味着定义不适合 Slot
的 MagicalWholeBodyArmor
,因此如果您尝试访问其 Slot
属性,则会引发异常。将MagicalWholeBodyArmor
视为IArmor
的人在尝试查看它适合哪个插槽时会大吃一惊。
您编写的代码确实违反了 SOLID 规则,即 开放/封闭原则。 Open/Closed 原则的一个很好的经验法则是“如果我更改这段代码,我还必须更改其他地方的多少其他代码位?”。如果答案是“很多”,那可能是因为您违反了开放/封闭原则。
在您的情况下,添加一个新的 EquipmentType
枚举成员意味着您必须在 Player
类中找到该 switch 语句并添加一个新的情况。
如果只有一个 switch 语句,那还不错。如果您添加了一种新型设备,那么您的Player
类可能需要升级无论如何,因此修改 switch 语句作为其中的一部分是可以的。尝试以自己的方式解决这个问题将意味着大量的抽象,而收益却很少。
但是,如果您在许多不同的地方有很多很多 switch 语句,它们都在查看 EquipmentType
,(并根据它做出不同的决定),那么您需要找到它们并全部修复它们,那么这就更严重地违反了开放/封闭原则,这可能表明您需要重新架构事物以将所有这些独立的、不同的逻辑位集中到一个地方。
【讨论】:
适用于java开发人员的solid设计原则简介
...么要SOLID?”的整个概念,以及如何实施设计模式,这需要时间和大量实践。我可以说实话,关于SOLID设计模式以及TD 查看详情
佰新视觉ui设计的实施需要注意哪些问题
...设计培训的小伙伴想要做的网页设计得更漂亮、更精致,需要注意哪些方面? 网站视觉设计的实施需要注意哪些问题。 一,布局简约大方。 设计者要注意的是,只有保证网页设计布局简约大方,才能减少用户... 查看详情
此 package.json 文件需要更改哪些内容才能使用 npm 0.3.0?
】此package.json文件需要更改哪些内容才能使用npm0.3.0?【英文标题】:Whatneedstochangeinthispackage.jsonfiletoworkwithnpm0.3.0?【发布时间】:2011-08-0409:41:39【问题描述】:尝试使用lib但出现此错误...npmERR!JSON.parseFailedtoparsepackage.jsondata.npmERR!... 查看详情
必须在客户端或服务器端更改哪些内容才能使 getJSON() 工作?
...:48【问题描述】:我正在使用一些已经创建的Web服务,我需要使用ajax调用它们。我正在处理的站点托管在与Web服务不同的域中。我现在知道这会导致同源策略的问题。我正在尝试使用JSON来解决 查看详情
我需要进行哪些更改才能执行上界的反转?
】我需要进行哪些更改才能执行上界的反转?【英文标题】:WhatisthechangeIneedtomaketoperformreverseofupper_bound?【发布时间】:2021-12-1219:45:31【问题描述】:我觉得c++stl中的lower_bound与upper_bound函数并不相反。默认情况下,在非递减数组... 查看详情
PHP 文件不会在浏览器中打开 - 只能下载。我需要进行哪些更改才能使其正常工作?
】PHP文件不会在浏览器中打开-只能下载。我需要进行哪些更改才能使其正常工作?【英文标题】:PHPFileswon\'topeninbrowser-onlydownload.WhatdoIneedtochangetomakeitworkproperly?【发布时间】:2011-07-2019:51:40【问题描述】:我已尝试重新安装PHP... 查看详情
所有 Python dunder 方法的列表 - 您需要实现哪些方法才能正确代理对象?
】所有Pythondunder方法的列表-您需要实现哪些方法才能正确代理对象?【英文标题】:ListofallPythondundermethods-Whichonesdoyouneedtoimplementtocorrectlyproxyanobject?【发布时间】:2019-10-0720:19:09【问题描述】:我正在尝试创建一个对象代理。属... 查看详情
需要进行哪些更改才能使此代码检测多个人脸而不是仅一个人脸
】需要进行哪些更改才能使此代码检测多个人脸而不是仅一个人脸【英文标题】:whatchangeisnecessarytomakethiscodedetectmultiplefacesratherthanonlyone【发布时间】:2018-08-1112:36:27【问题描述】:我是openCV和dlib模块的新手。我试图让这段代码... 查看详情
如何设计遵循 SOLID 的类而不在其他地方加载违反 SOLID 的内容?
】如何设计遵循SOLID的类而不在其他地方加载违反SOLID的内容?【英文标题】:HowcanIdesignclassesthatfollowSOLIDwithoutoffloadingviolationsofSOLIDsomewhereelse?【发布时间】:2017-12-2203:41:30【问题描述】:我的控制器违反了开闭原则。我试图弄清... 查看详情
需要在上下文类中进行哪些更改才能将连接字符串移动到 appsettings.json 文件中
】需要在上下文类中进行哪些更改才能将连接字符串移动到appsettings.json文件中【英文标题】:Whatchangesneedtobemadeincontextclasstomoveconnectionstringintoappsettings.jsonfile【发布时间】:2021-09-0623:09:22【问题描述】:我正在使用.NETCOREWEBAPI项... 查看详情
我应该在 app.json 文件中更改哪些内容以从 expo 重建我的应用程序?
】我应该在app.json文件中更改哪些内容以从expo重建我的应用程序?【英文标题】:WhatshouldIchangeintheapp.jsonfiletorebuildmyappfromexpo?【发布时间】:2020-03-1619:53:57【问题描述】:我计划重建我的应用程序。应该更改哪些设置才能从1.0.0... 查看详情
我需要在文件“/etc/php5/apache2/php.ini”中更改哪些内容以显示错误、警告、异常?我应该如何保存我所做的更改?
】我需要在文件“/etc/php5/apache2/php.ini”中更改哪些内容以显示错误、警告、异常?我应该如何保存我所做的更改?【英文标题】:Where&whatIneedtochangeinafile\'/etc/php5/apache2/php.ini\'todisplayerrors,warnings,exceptions?HowshouldIsavethechangesImade... 查看详情
如果维度/事实表中的数据未正确加载,我需要执行哪些步骤来清理数据
】如果维度/事实表中的数据未正确加载,我需要执行哪些步骤来清理数据【英文标题】:whatarethestepsIneedtoperformtocleanthedataifdataintothedimension/facttableimproperlyloaded【发布时间】:2020-11-0714:18:29【问题描述】:假设有一个场景,有一... 查看详情
erp系统成本包括哪些方面
...实施成本 必须由专业人员安装和配置ERP系统,因此您需要将这些实施成本包括在ERP系统的总价中。ERP系统是复杂的软件应用程序,因此您可能需要更改操作系统,升级或更改服务器以及更改在公司网络上使用的其他硬件和软... 查看详情
在 WebdriverIO 中,为啥 `expect` 行需要在其前面加上 `await` 才能正确测试某些内容?
】在WebdriverIO中,为啥`expect`行需要在其前面加上`await`才能正确测试某些内容?【英文标题】:InWebdriverIO,whydoesthe`expect`linerequirean`await`infrontofittocorrectlytestsomething?在WebdriverIO中,为什么`expect`行需要在其前面加上`await`才能正确测... 查看详情
轨道加密/解密
...n/decryption【发布时间】:2012-01-2307:46:42【问题描述】:我需要在我的Rails应用程序中进行加密和解密。我尝试使用ezcrypto,但每当我解密时都会出现此错误。OpenSSL::Cipher::CipherErrorinProfilesController#showwrongfinalblocklength需要更改哪些内... 查看详情
为了重新排列 UITableView 行,我必须实施哪些方法?
...示例,我必须在表控制器中实现什么来移动tableView行并将更改反映在我的数组中?【问题讨论】:【参考方案1】 查看详情
您需要来自计算机管理员的权限才能对此文件夹进行更改
...无法访问C:\……拒绝访问;2、删除文件夹时提示:您需要来自计算机管理员的权限才能对此文件夹进行更改。求助:删除这个垃圾管理员权限设置方法:1、选择文件夹或文件所有者用鼠标右键点击要操作的文件或文件夹,依... 查看详情