有时可以使用OO语言代替低级语言来直接与计算机交互。C ++当然可以,但是即使对于C#也有适配器等。尽管编写代码来控制机械零件并具有对内存的细微控制,但最好将其保持在尽可能低的水平。但是,如果这个问题与当前的面向对象软件(例如业务线,Web应用程序,IOT,Web服务以及大多数大规模使用的应用程序)有关,那么...
回答(如果适用)
读者可以尝试使用面向服务的体系结构(SOA)。也就是说,DDD,N层,N层,六边形等。我还没有看到大型企业应用程序有效地使用“传统” OO(活动记录或富模型),因为在过去的20年代70年代和80年代就已经描述过。(见注1)
问题不在OP上,但这个问题有两个问题。
您提供的示例只是为了演示多态性,它不是生产代码。有时,从字面上看就是完全一样的例子。
在FP和SOA中,数据与业务逻辑分开。也就是说,数据和逻辑不能并存。逻辑进入服务,并且数据(域模型)不具有多态行为(请参见注释2)。
服务和功能可以是多态的。在FP中,您经常将函数作为参数而不是值传递给其他函数。您可以在OO语言中使用Callable或Func之类的方法进行相同的操作,但是它不会运行得很猖((请参阅注释3)。在FP和SOA中,您的模型不是多态的,只有服务/功能。(见注4)
在该示例中,存在硬编码的不良情况。我不仅在谈论红色的字符串“狗吠”。我也在谈论CatModel和DogModel本身。如果要添加绵羊,会发生什么?您必须输入代码并创建新代码?为什么?在生产代码中,我宁愿仅看到带有其属性的AnimalModel。最糟糕的是,如果AmphibianModel和FowlModel的属性和处理方式如此不同,则将其替换。
我期望在当前的“ OO”语言中看到以下内容:
public class Animal
{
public int AnimalID { get; set; }
public int LegCount { get; set; }
public string Name { get; set; }
public string WhatISay { get; set; }
}
public class AnimalService : IManageAnimals
{
private IPersistAnimals _animalRepo;
public AnimalService(IPersistAnimals animalRepo) { _animalRepo = animalRepo; }
public List<Animal> GetAnimals() => _animalRepo.GetAnimals();
public string WhatDoISay(Animal animal)
{
if (!string.IsNullOrWhiteSpace(animal.WhatISay))
return animal.WhatISay;
return _animalRepo.GetAnimalNoise(animal.AnimalID);
}
}
您如何从OO中的类转换为函数式编程?正如其他人所说的;您可以,但实际上并非如此。上面的要点是要证明,当您使用Java和C#时,甚至不应该使用类(按照世界的传统意义)。一旦您开始在面向服务的体系结构(DDD,分层,分层,六边形等)中编写代码,您将离功能更近一步,因为您将数据(域模型)与逻辑功能(服务)分开了。
OO语言比FP更近一步
您甚至可以更进一步,将SOA服务分为两种类型。
可选类类型1:入口点的通用接口实现服务。这些将是“不纯的”入口点,可以调用“纯”或“不纯”其他功能。这可能是您来自RESTful API的入口点。
可选类类型2:纯业务逻辑服务。这些是具有“纯”功能的静态类。在FP中,“纯”表示没有副作用。它没有在任何地方显式设置State或Persistence。(见注5)
因此,当您想到面向服务的体系结构中使用的面向对象语言中的类时,它不仅使您的OO代码受益,而且还开始使函数式编程看起来非常容易理解。
笔记
注意1:原始的“丰富”或“活动记录”面向对象设计仍然存在。人们在十年或更早的时候“做正确的事”时,就有许多类似的遗留代码。上次我看到这种代码(正确完成)是来自C ++的视频游戏Codebase,在那里他们可以精确地控制内存并且空间非常有限。更不用说FP和面向服务的体系结构是野兽,不应该考虑硬件。但是它们将不断变化,维护,具有可变数据大小以及其他方面的能力作为优先事项。在视频游戏和机器AI中,您可以非常精确地控制信号和数据。
注2:域模型没有多态行为,也没有外部依赖关系。它们是“隔离的”。这并不意味着它们必须是100%贫血的。如果适用,它们可以具有与其构造和可变属性更改相关的许多逻辑。请参见Eric Evans和Mark Seemann撰写的DDD“值对象”和实体。
注3:Linq和Lambda是很常见的。但是,当用户创建新功能时,他们很少使用Func或Callable作为参数,而在FP中,看到一个没有遵循该模式的功能的应用会很奇怪。
注4:不要将多态与继承混淆。CatModel可以继承AnimalBase来确定Animal通常具有哪些属性。但正如我所展示的,这样的模型是Code Smell。如果看到此模式,则可以考虑将其分解并将其转换为数据。
注5:纯函数可以(也可以)接受函数作为参数。传入的函数可能不纯,但可能是纯函数。出于测试目的,它始终是纯净的。但是在生产中,尽管将其视为纯净的,但可能会产生副作用。这并不会改变纯函数是纯函数这一事实。虽然参数功能可能不正确。不要混淆!:D