C# 封装和委托抵销-不应';程序员的责任不是
1) 使用封装的一个原因是,通过隐藏内部实现细节,我们可以在不破坏现有代码的情况下修改这些细节——这非常有意义 a) 但我不理解这样的论点,即应该使用封装来防止用户将对象的内部数据设置为无效或不一致的状态 如果我编写一个类并将它卖给其他程序员(他们将这个类实现到自己的应用程序中),那么他们不应该负责以正确的方式访问这个对象吗?毕竟,如果他们没有正确地使用对象,那么只有他们的应用程序才会因此受到影响 一个类比(糟糕的类比)是,我必须实现封装,以便其他程序员不将内部数据(意外或故意)放入不一致状态,这就是销售防水电视,以防买家决定带着电视机游泳 2) 从C# 封装和委托抵销-不应';程序员的责任不是,c#,design-patterns,C#,Design Patterns,1) 使用封装的一个原因是,通过隐藏内部实现细节,我们可以在不破坏现有代码的情况下修改这些细节——这非常有意义 a) 但我不理解这样的论点,即应该使用封装来防止用户将对象的内部数据设置为无效或不一致的状态 如果我编写一个类并将它卖给其他程序员(他们将这个类实现到自己的应用程序中),那么他们不应该负责以正确的方式访问这个对象吗?毕竟,如果他们没有正确地使用对象,那么只有他们的应用程序才会因此受到影响 一个类比(糟糕的类比)是,我必须实现封装,以便其他程序员不将内部数据(意外或故意)放入不一致状态,
voidfoo(长颈鹿g){}
空栏(动物a){}
Action action1=Foo;//非法的
动作动作2=Bar;//合法的
为什么第一次转让是非法的?
因为action1的调用方可以通过
一只老虎,但福不能带走一只老虎,
只有一只长颈鹿!第二项任务
是合法的,因为酒吧可以接受任何
动物。«
我理解作者关于为什么Action action1
不能接受Foo()
的推理。但另一方面,程序员不应该把注册方法无法处理的任何参数传递给委托吗
因此,如果一些编程人员注册了方法Foo,那么他们也会知道:
•除了使用Giraffe
参数外,不要调用action1
委托
•不注册签名与Foo
不同的方法(除非方法将哺乳动物
派生的类型定义为其参数)
thanx你在这里真的问了两个问题,哪一个最好分开 听起来你真的不在乎类型安全,也不在乎试图引导人们走向成功 第二个问题很容易以非常具体的方式回答: 我理解作者关于原因的推理
操作1
不应
能够接受Foo()
。但另一方面
手,这不是程序员的吗
不进入的责任
委托任何已注册的参数
方法无法处理
哪个程序员?是创建操作
实例的那个,还是调用它的那个?这可能是两个完全不同的程序员,在完全不同的库中工作。为什么使用操作的程序员必须担心委托人实际上可能无法处理任何哺乳动物
?类型安全的全部要点是保证事物将正常工作。。。由于类型不匹配,您无法创建在执行时会崩溃的委托
如果您不关心编译时的类型安全性,也许您应该尝试使用动态类型语言。良好封装的优点之一是“强制”类的用户以正确的方式使用它,而不是以任何其他可能的方式。这样,用户对他必须(重新)使用的代码就不那么沮丧了。生产力提高了(花更少的时间找出代码为什么会中断,特别是在源代码不可用的情况下),等等
如果我必须从别人那里买一个图书馆,我必须非常小心地在每一步上使用它,我会认为我浪费了钱。
(我排除了库设计主题、稳定性、可维护性和可扩展性。我是凡人,涵盖这些方面的时间有限:)…)我认为您的代码应该始终是类型安全的。举个例子:人A写了一个类R,然后卖给人B。人A无法控制人B用这个类做什么。B可以将R类扩展到另一个S类,并将其出售给其他人。无法确保生产的非类型安全A级适用于所有使用Bs S级的用户。您的电视机类比意味着您需要预测代码使用的所有可能情况,这是不可能的。相反,想想你在做什么,让你的意图变得显而易见。您知道关于对象使用的这些细节,那么为什么不封装它们而不是将责任放在消费者身上呢
另一个类比是,你可以在你的门口没有门,并宣布世界有责任不进来;这不会改变一扇打开的门激发人们好奇心的力量。门的意思是“你不允许进入这所房子”,没有人会在运行时走进去发现,你抛出了AccessDeniedException。门的意图是非常明显的。我想最好用代码来表达它:所以这里是(重点在最后一部分的注释中)
免责声明:该代码不可编译,不应
public interface AnimalHandler
{
Action<Mammal> Feed{get;}
}
public class CreatedInFarAwayFromYou : AnimalHandler
{
private void Foo(Giraffe g) {}
public Action<Mammal> Feed
{
return Foo;
}
}
public class MadeByYou
{
private IEnumerable<Tiger> tigers;
AnimalHandler handler;
public void FeedAll()
{
foreach(var animal in tigers)
{
//You are by your reasoning at fault here. Not the dev that made CreatedInFarAwayFromYou
Feed(animal);
}
}
}
公共接口AnimalHandler
{
动作提要{get;}
}
公共类CreatedInFarAwayFromYou:AnimalHandler
{
私人长颈鹿{}
公共行动提要
{
返回Foo;
}
}
公共课马德比尤
{
私人老虎;
动物处理者;
公众免费FeedAll()
{
foreach(老虎的变种动物)
{
//这是你的错,不是你的开发者
饲料(动物);
}
}
}
诸如此类,诸如此类,我们到底为什么需要安全网,诸如此类。所以,成功的秘诀是胡说八道?更恰当的电视比喻是,你可以在电视机前盖上一个带有按钮的外壳,以避免意外
public interface AnimalHandler
{
Action<Mammal> Feed{get;}
}
public class CreatedInFarAwayFromYou : AnimalHandler
{
private void Foo(Giraffe g) {}
public Action<Mammal> Feed
{
return Foo;
}
}
public class MadeByYou
{
private IEnumerable<Tiger> tigers;
AnimalHandler handler;
public void FeedAll()
{
foreach(var animal in tigers)
{
//You are by your reasoning at fault here. Not the dev that made CreatedInFarAwayFromYou
Feed(animal);
}
}
}