当然,语言本身只会影响首选的风格。 即使在像 Haskell 这样的纯函数语言中,您也可以以过程式风格编写(尽管这是非常不鼓励的),甚至在像 C 这样的过程性语言中,您也可以以面向对象的风格进行编程(例如在 GTK+ 和EFL API)。
需要明确的是,每个范例的“优势”仅仅在于算法和数据结构的建模。 例如,如果您的算法涉及列表和树,那么函数式算法可能是最明智的。 或者,例如,如果您的数据是高度结构化的,那么将其组合为对象(如果这是您语言的本机范例)可能更有意义 - 或者,它可以很容易地编写为单子的功能抽象,这是 Haskell 或 ML 等语言的原生范例。
您使用的选择只是对您的项目和您的语言支持的抽象更有意义。
All of them are good in their own ways - They're simply different approaches to the same problems.
In a purely procedural style, data tends to be highly decoupled from the functions that operate on it.
In an object oriented style, data tends to carry with it a collection of functions.
In a functional style, data and functions tend toward having more in common with each other (as in Lisp and Scheme) while offering more flexibility in terms of how functions are actually used. Algorithms tend also to be defined in terms of recursion and composition rather than loops and iteration.
Of course, the language itself only influences which style is preferred. Even in a pure-functional language like Haskell, you can write in a procedural style (though that is highly discouraged), and even in a procedural language like C, you can program in an object-oriented style (such as in the GTK+ and EFL APIs).
To be clear, the "advantage" of each paradigm is simply in the modeling of your algorithms and data structures. If, for example, your algorithm involves lists and trees, a functional algorithm may be the most sensible. Or, if, for example, your data is highly structured, it may make more sense to compose it as objects if that is the native paradigm of your language - or, it could just as easily be written as a functional abstraction of monads, which is the native paradigm of languages like Haskell or ML.
The choice of which you use is simply what makes more sense for your project and the abstractions your language supports.
I think the available libraries, tools, examples, and communities completely trumps the paradigm these days. For example, ML (or whatever) might be the ultimate all-purpose programming language but if you can't get any good libraries for what you are doing you're screwed.
For example, if you're making a video game, there are more good code examples and SDKs in C++, so you're probably better off with that. For a small web application, there are some great Python, PHP, and Ruby frameworks that'll get you off and running very quickly. Java is a great choice for larger projects because of the compile-time checking and enterprise libraries and platforms.
It used to be the case that the standard libraries for different languages were pretty small and easily replicated - C, C++, Assembler, ML, LISP, etc.. came with the basics, but tended to chicken out when it came to standardizing on things like network communications, encryption, graphics, data file formats (including XML), even basic data structures like balanced trees and hashtables were left out!
Modern languages like Python, PHP, Ruby, and Java now come with a far more decent standard library and have many good third party libraries you can easily use, thanks in great part to their adoption of namespaces to keep libraries from colliding with one another, and garbage collection to standardize the memory management schemes of the libraries.
These paradigms don't have to be mutually exclusive. If you look at python, it supports functions and classes, but at the same time, everything is an object, including functions. You can mix and match functional/oop/procedural style all in one piece of code.
What I mean is, in functional languages (at least in Haskell, the only one I studied) there are no statements! functions are only allowed one expression inside them!! BUT, functions are first-class citizens, you can pass them around as parameters, along with a bunch of other abilities. They can do powerful things with few lines of code.
While in a procedural language like C, the only way you can pass functions around is by using function pointers, and that alone doesn't enable many powerful tasks.
In python, a function is a first-class citizen, but it can contain arbitrary number of statements. So you can have a function that contains procedural code, but you can pass it around just like functional languages.
Same goes for OOP. A language like Java doesn't allow you to write procedures/functions outside of a class. The only way to pass a function around is to wrap it in an object that implements that function, and then pass that object around.
For GUI I'd say that the Object-Oriented Paradigma is very well suited. The Window is an Object, the Textboxes are Objects, and the Okay-Button is one too. On the other Hand stuff like String Processing can be done with much less overhead and therefore more straightforward with simple procedural paradigma.
I don't think it is a question of the language neither. You can write functional, procedural or object-oriented in almost any popular language, although it might be some additional effort in some.
In order to answer your question, we need two elements:
Understanding of the characteristics of different architecture styles/patterns.
Understanding of the characteristics of different programming paradigms.
A list of software architecture styles/pattern is shown on the software architecture article on Wikipeida. And you can research on them easily on the web.
In short and general, Procedural is good for a model that follows a procedure, OOP is good for design, and Functional is good for high level programming.
I think you should try reading the history on each paradigm and see why people create it and you can understand them easily.
After understanding them both, you can link the items of architecture styles/patterns to programming paradigms.
I think that they are often not "versus", but you can combine them. I also think that oftentimes, the words you mention are just buzzwords. There are few people who actually know what "object-oriented" means, even if they are the fiercest evangelists of it.
b) 您可以使用一致的命名策略并使用分而治之的方法来创建程序。 它不会有任何继承,但由于您的函数很小、易于理解且格式一致,因此您不需要它。 您需要编写的代码量不断增加,很难保持专注并且不屈服于简单的解决方案(黑客)。 然而,这种忍者的编码方式是C的编码方式。 在低级自由和编写良好代码之间保持平衡。 实现这一目标的好方法是使用函数式语言编写原型。 例如,Haskell 非常适合原型算法。
我倾向于方法b。 我使用方法 a 编写了一个可能的解决方案,老实说,使用该代码感觉非常不自然。
One of my friends is writing a graphics app using NVIDIA CUDA. Application fits in very nicely with OOP paradigm and the problem can be decomposed into modules neatly. However, to use CUDA you need to use C, which doesn't support inheritance. Therefore, you need to be clever.
a) You devise a clever system which will emulate inheritance to a certain extent. It can be done!
i) You can use a hook system, which expects every child C of parent P to have a certain override for function F. You can make children register their overrides, which will be stored and called when required.
ii) You can use struct memory alignment feature to cast children into parents.
This can be neat but it's not easy to come up with future-proof, reliable solution. You will spend lots of time designing the system and there is no guarantee that you won't run into problems half-way through the project. Implementing multiple inheritance is even harder, if not almost impossible.
b) You can use consistent naming policy and use divide and conquer approach to create a program. It won't have any inheritance but because your functions are small, easy-to-understand and consistently formatted you don't need it. The amount of code you need to write goes up, it's very hard to stay focused and not succumb to easy solutions (hacks). However, this ninja way of coding is the C way of coding. Staying in balance between low-level freedom and writing good code. Good way to achieve this is to write prototypes using a functional language. For example, Haskell is extremely good for prototyping algorithms.
I tend towards approach b. I wrote a possible solution using approach a, and I will be honest, it felt very unnatural using that code.
发布评论
评论(7)
它们都有自己的优点——它们只是解决相同问题的不同方法。
在纯粹的过程风格中,数据往往与对其进行操作的函数高度解耦。
在面向对象的风格中,数据往往带有函数的集合。
在函数式风格中,数据和函数往往彼此有更多共同点(如 Lisp 和 Scheme),同时在函数的实际使用方式方面提供更大的灵活性。 算法也倾向于根据递归和组合而不是循环和迭代来定义。
当然,语言本身只会影响首选的风格。 即使在像 Haskell 这样的纯函数语言中,您也可以以过程式风格编写(尽管这是非常不鼓励的),甚至在像 C 这样的过程性语言中,您也可以以面向对象的风格进行编程(例如在 GTK+ 和EFL API)。
需要明确的是,每个范例的“优势”仅仅在于算法和数据结构的建模。 例如,如果您的算法涉及列表和树,那么函数式算法可能是最明智的。 或者,例如,如果您的数据是高度结构化的,那么将其组合为对象(如果这是您语言的本机范例)可能更有意义 - 或者,它可以很容易地编写为单子的功能抽象,这是 Haskell 或 ML 等语言的原生范例。
您使用的选择只是对您的项目和您的语言支持的抽象更有意义。
All of them are good in their own ways - They're simply different approaches to the same problems.
In a purely procedural style, data tends to be highly decoupled from the functions that operate on it.
In an object oriented style, data tends to carry with it a collection of functions.
In a functional style, data and functions tend toward having more in common with each other (as in Lisp and Scheme) while offering more flexibility in terms of how functions are actually used. Algorithms tend also to be defined in terms of recursion and composition rather than loops and iteration.
Of course, the language itself only influences which style is preferred. Even in a pure-functional language like Haskell, you can write in a procedural style (though that is highly discouraged), and even in a procedural language like C, you can program in an object-oriented style (such as in the GTK+ and EFL APIs).
To be clear, the "advantage" of each paradigm is simply in the modeling of your algorithms and data structures. If, for example, your algorithm involves lists and trees, a functional algorithm may be the most sensible. Or, if, for example, your data is highly structured, it may make more sense to compose it as objects if that is the native paradigm of your language - or, it could just as easily be written as a functional abstraction of monads, which is the native paradigm of languages like Haskell or ML.
The choice of which you use is simply what makes more sense for your project and the abstractions your language supports.
我认为现在可用的库、工具、示例和社区完全胜过了范式。 例如,机器学习(或其他)可能是最终的通用编程语言,但如果您无法为您正在做的事情获得任何好的库,那么您就完蛋了。
例如,如果您正在制作视频游戏,那么 C++ 中有更多优秀的代码示例和 SDK,因此您可能会更好。 对于小型 Web 应用程序,有一些很棒的 Python、PHP 和 Ruby 框架可以让您快速上手并运行。 由于编译时检查以及企业库和平台,Java 是大型项目的绝佳选择。
过去的情况是,不同语言的标准库非常小并且很容易复制 - C、C++、Assembler、ML、LISP 等。都有基础知识,但在标准化方面往往会畏缩像网络通信、加密、图形、数据文件格式(包括 XML),甚至像平衡树和哈希表这样的基本数据结构都被遗漏了!
Python、PHP、Ruby 和 Java 等现代语言现在拥有一个更加体面的标准库,并且有许多可以轻松使用的优秀第三方库,这在很大程度上要归功于它们采用命名空间来防止库相互冲突,和垃圾收集来标准化库的内存管理方案。
I think the available libraries, tools, examples, and communities completely trumps the paradigm these days. For example, ML (or whatever) might be the ultimate all-purpose programming language but if you can't get any good libraries for what you are doing you're screwed.
For example, if you're making a video game, there are more good code examples and SDKs in C++, so you're probably better off with that. For a small web application, there are some great Python, PHP, and Ruby frameworks that'll get you off and running very quickly. Java is a great choice for larger projects because of the compile-time checking and enterprise libraries and platforms.
It used to be the case that the standard libraries for different languages were pretty small and easily replicated - C, C++, Assembler, ML, LISP, etc.. came with the basics, but tended to chicken out when it came to standardizing on things like network communications, encryption, graphics, data file formats (including XML), even basic data structures like balanced trees and hashtables were left out!
Modern languages like Python, PHP, Ruby, and Java now come with a far more decent standard library and have many good third party libraries you can easily use, thanks in great part to their adoption of namespaces to keep libraries from colliding with one another, and garbage collection to standardize the memory management schemes of the libraries.
这些范例不一定是相互排斥的。 如果你看看Python,它支持函数和类,但同时,一切都是对象,包括函数。 您可以在一段代码中混合和匹配函数式/oop/过程式风格。
我的意思是,在函数式语言中(至少在 Haskell 中,我研究的唯一一种)没有语句! 函数内部只允许有一个表达式! 但是,函数是一等公民,您可以将它们作为参数以及许多其他功能传递。 他们可以用几行代码完成强大的事情。
而在像 C 这样的过程语言中,传递函数的唯一方法是使用函数指针,而仅此并不能实现许多强大的任务。
在Python中,函数是一等公民,但它可以包含任意数量的语句。 因此,您可以拥有一个包含过程代码的函数,但您可以像函数式语言一样传递它。
OOP 也是如此。 像 Java 这样的语言不允许您在类之外编写过程/函数。 传递函数的唯一方法是将其包装在实现该函数的对象中,然后传递该对象。
在 Python 中,则没有此限制。
These paradigms don't have to be mutually exclusive. If you look at python, it supports functions and classes, but at the same time, everything is an object, including functions. You can mix and match functional/oop/procedural style all in one piece of code.
What I mean is, in functional languages (at least in Haskell, the only one I studied) there are no statements! functions are only allowed one expression inside them!! BUT, functions are first-class citizens, you can pass them around as parameters, along with a bunch of other abilities. They can do powerful things with few lines of code.
While in a procedural language like C, the only way you can pass functions around is by using function pointers, and that alone doesn't enable many powerful tasks.
In python, a function is a first-class citizen, but it can contain arbitrary number of statements. So you can have a function that contains procedural code, but you can pass it around just like functional languages.
Same goes for OOP. A language like Java doesn't allow you to write procedures/functions outside of a class. The only way to pass a function around is to wrap it in an object that implements that function, and then pass that object around.
In Python, you don't have this restriction.
对于 GUI,我想说面向对象范式非常适合。 窗口是一个对象,文本框是对象,“确定”按钮也是对象。 另一方面,像字符串处理这样的事情可以用更少的开销来完成,因此使用简单的过程范式更加简单。
我认为这也不是语言的问题。 您可以用几乎任何流行的语言编写函数式、过程式或面向对象的语言,尽管在某些语言中这可能需要一些额外的努力。
For GUI I'd say that the Object-Oriented Paradigma is very well suited. The Window is an Object, the Textboxes are Objects, and the Okay-Button is one too. On the other Hand stuff like String Processing can be done with much less overhead and therefore more straightforward with simple procedural paradigma.
I don't think it is a question of the language neither. You can write functional, procedural or object-oriented in almost any popular language, although it might be some additional effort in some.
为了回答您的问题,我们需要两个要素:
Wikipeida 上的软件架构文章显示了软件架构风格/模式的列表。 您可以在网络上轻松研究它们。
简而言之,过程式适合遵循过程的模型,OOP 适合设计,功能性适合高级编程。
我认为你应该尝试阅读每个范式的历史,看看人们为什么创造它,你可以很容易地理解它们。
了解它们之后,您可以将架构风格/模式的项目与编程范例联系起来。
In order to answer your question, we need two elements:
A list of software architecture styles/pattern is shown on the software architecture article on Wikipeida. And you can research on them easily on the web.
In short and general, Procedural is good for a model that follows a procedure, OOP is good for design, and Functional is good for high level programming.
I think you should try reading the history on each paradigm and see why people create it and you can understand them easily.
After understanding them both, you can link the items of architecture styles/patterns to programming paradigms.
我认为它们往往不是“对抗”的,但你可以将它们结合起来。 我还认为,很多时候,你提到的词只是流行语。 很少有人真正了解“面向对象”的含义,即使他们是最狂热的传播者。
I think that they are often not "versus", but you can combine them. I also think that oftentimes, the words you mention are just buzzwords. There are few people who actually know what "object-oriented" means, even if they are the fiercest evangelists of it.
我的一位朋友正在使用 NVIDIA CUDA 编写图形应用程序。 应用程序非常适合 OOP 范式,并且问题可以巧妙地分解为模块。 但是,要使用 CUDA,您需要使用 C,它不支持继承 。 因此,你需要聪明一点。
a) 你设计了一个聪明的系统,它将在一定程度上模拟继承。 可以办到!
i) 你可以使用hook系统,它期望父P的每个子C都有一个函数 F 的某些覆盖。您可以让子级注册他们的覆盖,这些覆盖将被存储并在需要时调用。
ii) 您可以使用 struct 内存对齐 功能将子项转换为父项。
这可能很简洁,但想出面向未来的可靠解决方案并不容易。 您将花费大量时间设计系统,并且不能保证您不会在项目中途遇到问题。 实现多重继承甚至更难,即使不是几乎不可能。
b) 您可以使用一致的命名策略并使用分而治之的方法来创建程序。 它不会有任何继承,但由于您的函数很小、易于理解且格式一致,因此您不需要它。 您需要编写的代码量不断增加,很难保持专注并且不屈服于简单的解决方案(黑客)。 然而,这种忍者的编码方式是C的编码方式。 在低级自由和编写良好代码之间保持平衡。 实现这一目标的好方法是使用函数式语言编写原型。 例如,Haskell 非常适合原型算法。
我倾向于方法b。 我使用方法 a 编写了一个可能的解决方案,老实说,使用该代码感觉非常不自然。
One of my friends is writing a graphics app using NVIDIA CUDA. Application fits in very nicely with OOP paradigm and the problem can be decomposed into modules neatly. However, to use CUDA you need to use C, which doesn't support inheritance. Therefore, you need to be clever.
a) You devise a clever system which will emulate inheritance to a certain extent. It can be done!
i) You can use a hook system, which expects every child C of parent P to have a certain override for function F. You can make children register their overrides, which will be stored and called when required.
ii) You can use struct memory alignment feature to cast children into parents.
This can be neat but it's not easy to come up with future-proof, reliable solution. You will spend lots of time designing the system and there is no guarantee that you won't run into problems half-way through the project. Implementing multiple inheritance is even harder, if not almost impossible.
b) You can use consistent naming policy and use divide and conquer approach to create a program. It won't have any inheritance but because your functions are small, easy-to-understand and consistently formatted you don't need it. The amount of code you need to write goes up, it's very hard to stay focused and not succumb to easy solutions (hacks). However, this ninja way of coding is the C way of coding. Staying in balance between low-level freedom and writing good code. Good way to achieve this is to write prototypes using a functional language. For example, Haskell is extremely good for prototyping algorithms.
I tend towards approach b. I wrote a possible solution using approach a, and I will be honest, it felt very unnatural using that code.