Observations on design pattern use in Java vs. C#
Steve Yegge's OOP version of the proverb "for the lack of a nail, the battle was lost"

Observations on design pattern use in Java vs. C#

I'm fond of saying that most problems in software engineering are due to one thing trying to do two or more things, or two or more things trying to do the same thing (this could be true of functions, classes or even human engineers).

Even though design patterns in programming languages such as Java and C# are meant to discourage this tendency, my early experiences with Java (circa 2002 - 2006) managed to put me off design patterns for a long time.

At the height of popularity of OOP/GoF design patterns, you had to wade through layers of Factory, Adapter, Mediator, Command and other patterns to find the one function call that actually did the work. If you want to read a more brutal takedown of that trend, you might want to read Steve Yegge's famous rant, Execution in the Kingdom of Nouns.

In that era, this is (roughly) how you would read a file in Java (code from OpenAI GPT):

Here's how you'd do it (again, roughly) in C:

So naturally, I stuck with languages such as C++, JavaScript, Python and Golang for most of my career -- all languages that were not militant about OOP, and allowed you to write fairly functional code.

But recently, I've been working on some large, enterprise level C# code bases, and I'm finding that perhaps the .NET world has, at some point in the past few years, struck a reasonable balance between OOP and functional programming.

I've found the common pattern of Controllers, DTOs, Models, Repositories, Services and Proxies can make very large code bases consistent, readable and therefore easier to modify. Without going too far, this pattern manages to solve the problem of "one thing trying to do two or more things", or at the risk of attracting architecture astronauts, "separation of concerns": Models represent data at rest, Repositories perform CRUD operations on said data, Services provide business logic on top of data, Proxies provide access to external services, Controllers handle requests, and data is passed between these different constructs using DTOs. For example, if you want to know where products are fetched from a third party API, you know the code will be found in only one place: ProductProxy; if you want to know where it is updated in the database, you know it will always be in the ProductRepository etc.


Source:

I'm still not sold on Mediators and Commands, and I probably would not replicate the above patterns in JavaScript or Golang, but at least in the context of .NET Web APIs, they seem to work adequately. Thoughts on Clean Architecture, I will keep for another day (because for me, "architecture" and "how code is organized" are two different things).

Yashodha Athureliyage

Expertise in .Net Full-Stack | Blazor | React | Angular

1 个月

This kind of ecosystem-specific architectural evaluation is refreshing. Looking forward to your thoughts on Clean Architecture, particularly given your intriguing distinction between architecture and code organization patterns. That's a perspective worth exploring deeper.

Harsha Rathnayaka

Senior Software Engineer at ICP Techno LLC

1 个月

Very informative

回复

要查看或添加评论,请登录

Hasitha Liyanage的更多文章

社区洞察

其他会员也浏览了