After years of studying and working a programmer who is interested in design gathers rules and tips directing her/him towards better design. I am compiling my own list here. This list is going to grow over time.
Static Methods are often bad
Static methods don't use internal state of the class in which they are defined, they raise questions like: why methods that don't use fields of the class exist in this class? Do they belong to another class?
Info/DTO classes are bad
In a very inaccurate and vague definition, a Class is a combination of methods and fields. A class that doesn't have methods raises questions like: where are functions that work on the fields/properties of this class? (Are the methods scattered throughout the rest of the code instead of being inside the class?) Is this merely a data structure defined mistakenly as 'Class'?
CQS is good
Not to be mistaken with CQRS, basically states 'getter's should not change state of the object and 'setter's should not return anything. I am not sure about setter methods but I am darn certain that almost always changing state in getters is a terrible idea.
TDD is good
TDD can result in good design or bad design (test-induced design damage). Moreover, TDD does not guarantee an algorithm or a piece of code is always correct, though it can prove incorrectness of the algorithm. On the other hand, I haven't come across any solution that guarantees 100% correctness of an algorithm, so TDD is not to blame here. On the plus side, TDD often results in early changes to smallest pieces of code which increases code quality over time, moreover, it increases our confidence in refactoring code so IMHO TDD is more helpful than harmful.
Layered architecture is probably bad!
Layered (aka N-Tier) architecture breaks code into separate layers. These layers, communicate using an agreed-upon interface. To share data between layers, either a common library is added to the solution holding common DTOs/Entities or if layers communicate via services (especially restful services) then a separate set of DTOs on each layer is used to transfer data to other layers. The problem is that the logic from Domain Model entities that are mapped into such DTOs are often duplicated in the next layer. The need for duplicated logic means that logically related classes are physically separated which means low cohesion. So, it is not the layered architecture that has problems rather it is the way layers are defined and the reasoning for breaking application into layers that causes the problem.
Windows 10 is stable now. Upgraded from Windows 7 to 10 (for like 4th time! but this time everything went) very smoothly. The OS is now MUCH more stable than it used to be a few months ago. Andromeda and Polaris show that finally MS has a clear direction (bold goals which I love, admirable Microsoft, respect!). Watched this video the other day:
I cannot wait to work with Asp.net core and web assemblies, specifically Blazor to build good software products.
A decade ago I found myself searching for "how to live" online! Suddenly I thought, whoa! What am I doing?! Do I really not know how to live?! Should someone else teach me THAT?!
Now, I know I actually didn't know how to live! I believe 'how to live a good life' must be thought in schools. In my 20s all I considered as 'important' was software, programming, and a good job! That was the problem. My parents or my teachers never thought me to have diversity and dimension in life. Their benevolent advise was to study hard in school and work hard afterward. However, doing only that, makes life so boring and meaningless. Later I learned that work is just one part of life and it's not a prerequisite to many other parts. In my 30s I learned how to live, I guess. Moreover, I learned how to tackle life problems using my abilities AND help of other people. Furthermore, I learned listening and learning, almost everyone has something to teach.
If I have a family and kids one day, I will encourage them to learn playing music, to take studying human science, sports and even dancing just as seriously as their professional work. I encourage them to socialize and enjoy observing other peoples' interesting thoughts and approaches to life.
Humans have three major needs, IMO; needs inside including physical and mental needs, as well as need to communicate with the outside world; relationships. Thus, 1 dimensional growth will not be fulfilling. I believe, happiness shows itself when we are physically and mentally healthy and also live together with other happy healthy people.
Why did I switched back? Drivers and my professional background.
I had a relatively long experience of Linux. It was awesome. Linux guys have done an amazing job, improvements of the OS is unbelievable.
Unfortunately graphics and sound quality was not perfect due to bad drivers. This month I needed extensive use of microphone for the purpose of communication and didn't want to hear people complain all the time.
The second reason is my professional background in Windows programming. It takes years to gain the same level of expertise in Java/Linux stack.
In comparison, Windows 7 is better than Linux ON MY MAIN COMPUTER; Windows 10 is not. I hope managers of the Asp.Net Core team gain control of the Windows team, in such a condition, we might see a fast and visually unified OS from Microsoft again.
As it's often the case in software engineering(!) there is no commonly accepted term referring to programmers with multiple skills that allow them to analyze, develop, and deploy most parts of complex and large solutions. Some call such developers end to end and some other call them full stack, I call them (me included) general programmer. The market for us is shrinking or will be shrinking, I believe. Much like a general doctor, a general programmer serves far less purpose as time goes by.
Back when I started, a Bachelor's degree plus one more book to read (the famous Charles Petzold book) was all one needed to rule the world of programming! The only major OS was MS Windows after all! Tings are entirely different nowadays and no single human being can cope with so many changes and so many books to read in order to be a good general programmer. Moreover, math is taking over! Algorithms are gaining more and more attraction and technology and coding tools and languages are becoming less important (there are so many educated professionals out there).
I think it is time to start thinking about stepping into a narrower path to hopefully become a specialist.
I guess it's more than a year that I switched from Windows to Linux (after 20 years of using Windows exclusively). As odd as it sounds I must say I am happy with that final decision. My experience with Linux (Debian) has been great; it just works!
I switched because of three main reasons;
1. The time wasted fighting with Windows (e.g. huge updates taking forever to download and install and restart becoming nearly a daily task! damn Agile!!, tweaking something here something there. Preventing certain updates from installing, etc.)
2. Windows rot(Computer was crawling after a few years! impossible to work with). The damn hard disk LED was never off. I stopped system restore, indexing and any other services I thought might be remotely related, no luck! I changed my anti virus software and also switched from ZoneAlarm to Win7/8 Firewall Control, still no luck.
3. Windows 8.X and then 10! I call them spywares that care about spying more than user experience. In every second of working with Windows 10 you'd notice something broken, something not working the way it's supposed to do! A click on a menu: sometimes it opens sometimes it doesn't. All of a sudden a network I attempted to disable locks up entire network section GUI of control panel. Then, nothing works unless the entire system is restarted! Terrible days! I don't miss them!
These days I rarely see hdd LED of my laptop blinking! It's so rare that I notice when it does! Even though Intel and NVidia drivers aren't developed for Linux as perfect as they are for Windows, they get the job done for me.
I still use Windows but inside a VirtualBox virtual machine to switch on only when needed.
Perhaps the time has come to switch professionally too. I spent a long time to master .Net and C# but seeing what MS is planning to do to Asp.Net Core, and remembering what they did to MFC and then .Net by introduction of UWP I feel like it's time to say goodbye to Microsoft forever. It's a pity though. I used to love the company, I used to love their products. They were the best. I even dreamed about becoming an MVP when I was younger.
All I learned from the past wrong choices are that firstly, greed and arrogance form a deadly combination. Furthermore, not every change is worth it. Computer software is facing a big problem, IMO, which is changes that are becoming more and more extreme with gains becoming smaller and smaller; reinventing the same wheel over and over again. Learning something new that is not much better does not feel like improving and kills a lot of energy and time that could be spent on building cool stuff. Finally, I learned to study thoroughly before picking a new technology to learn.
I have been studying Object Oriented design principles, practices, and patterns for a long time. I have used many of them in my code and now that I look back I see common patterns in everything even these principles!
I believe most of what programmers learn is algorithms, written with different intentions, of course. Back when I started learning algorithms, the goal was to have highest possible performance; remember how O(log n) was much better than O(n)?!
But, reading design books I learned in real life what matters the most is decreasing costs. Main source of cost seems to be that caused by CHANGE. So, we are taught new set of algorithms called OO patterns. These algorithms are not created with the aim of high performance but instead they are to make code readable, maintainable, and changeable in long run.
When it comes to scalability we learn new ways of doing the same thing, we learn about distributed systems. The interesting part is that higher performance is not of much importance here either because no matter how high performant a code is eventually users might outnumber it! So what matters is to be able to change scale the system by adding hardware whenever required. This requires new techniques and familiarity with new science and tools.
So, I believe what we are learning all the time is different algorithms each tailored to a specific goal, to solve a specific problem. Much as we write an algorithm to solve a math problem we have broader algorithms to solve scalability, maintainability, performance, globalization, and other problems software deals with. Although they are given different names, essentially they are only different algorithms.
I find myself a man who looks for patterns that require certain algorithms to change them into more demanding patterns!
I escaped from a society in which the norm for long term relationship was traditional marriage in which case two people could spend a very short time (one or two 1-hour session perhaps) under supervision of their parents to get to 'know each other'!
I know it is possible to judge someone's sanity in perhaps a short session but, really, how much can two people 'know' each other or learn about each other in an 1-hour session?
Job, IMO, is a form of a long term relationship (at least many companies hope it to be) yet recruitment processes remind me of the traditional marriage; short interview sessions often ending up with misjudgments or misunderstandings about one another and letting those who shouldn't in yet keeping many qualified people out.
Some have gone as far as creating businesses around it to teach us how to please interviewers by learning satisfying answers; I feel it's kind of cheating!
I hope there was a way to escape traditional job interviews or some more reasonable solutions invented! (I also hope a recruiter who is going to interview me next never read this!!)
If you have worked with layered architecture and an ORM for a while you probably have a set of repository classes with some GetSomething methods to return records (probably mapped to objects) from database. To prevent loading all objects you probably have some conditional statements that are applied to query before linq executes them like this:
public SomeObjectList RepoMethod(bool includeRelatedRecordSet1)
vr query = context.AllObjects.Where(condition);
if (includeRelatedRecordSet1) query = query.Include(q => q.RelatedRecordSet1);
The problem is that as time passes and applications get more and more complex the list of parameters increases and we endue recreating LINQ albeit in an ugly way!
We don't want to return query and execute it + map results using LINQ outside repository for design reasons, we don't want to return all mapped records and then execute LINQ on objects outside the repository for performance reasons. What should we do? Should we accept linq to object queries as input parameter (lambda) and map these queries to ORM queries? Seems like too much work. Looking for a solution...
A class that is somewhat dumber than Linq but more flexible than Repository produces better results. For example this is the code using the class:
var friends =
Microsoft already has the best programming languages in the world; C# and F#. They have the best IDE too (Once installed and ran though! Installer of the latest version (14 AKA 2015) really sucks and also it is becoming too slow to start but once started, and especially if Resharper is installed too, it cannot be beaten.)
However, all of these might become obsolete in no time. IF desktop programming becomes obsolete, these tools won't be of much use in such a future either.
Microsoft could create the best cross-platform solution for developing mobile apps and it's not the way Xamarin has done it. Xamarin has made it way too complex. The genius designer of "CodeName One" has done it though, IMO.
Regardless of the idea that Web will rule the future (advocated of that idea believe it will happen the same way web ate large portion of native desktop app market-share), for native app development I see no better solution than CodeName One.
CodeName One has done the difficult part of the job and actually has done it in a very efficient way! The GUI is rendered using OpenGL. That means creating UI has become easy because we no longer deal with two or more distinct native platforms and especially we no longer deal with crap set of apis that Google has created for Android. We can focus on one easy to use framework. Customization is possible and sometimes not that difficult either.
Microsoft could use this idea and empower C# developers this way. They could win developers developers developers again!
It's more than a month in Ubuntu 14.04 and everything is fine. At lease, as fine as it used to be in Win 8.1 and much finer than Win 10. I am still discovering this new world which is extremely exciting. It's scary how much of the world I have missed though!!
Today, I found and began experimenting with IntelliJ; an IDE that looks very much like MS Visual Studio (With a free community edition!). I'm not sure if it is as good as VS (until v. 12), yet. I am willing to try CodeNameOne with Java using this IDE. I'll write more about my experience.
UPDATE: I switched to Debian after a few weeks of using Ubuntu. For some reason Ubuntu was unable to keep my display back-light settings between restarts so I switched to Debian and things has worked perfectly smoothly for the past year.
One of my fantasies has been to read a mysterious lyric inside of which there are lines referring to other songs (probably by mentioning their name or a line of their lyrics).
I know advertisement experts would misuse that and it will eventually be a "music as a service" thing in which a lyric earns money by introducing songs of others (others who pay to be introduced of course!) inside songs of the most famous ones but still the initial lyric would be extremely fun. Figuring out what is the hidden lyric would be kinda of fun too.
This means connecting lyrics, and in a way, songs to each other!
Trying to create a little project with Asp.Net 5 preview I noticed a project I have moved into another virtual machine can't run in IIS Express. The problem turned out to be a path to the old directory somewhere stored inside a directory called ".vs". Deleting the directory and reopening the project fixed everything.
Just delete the ".vs" directory in case you moved your solution to another drive. VS can build it again.
After over 20 years of being a user of Microsoft Windows OS and related products and over 10 years of programming for it professionally, I decided to check out latest status of Linux again. I did and it is frightening!
Last time I tried Linux was when I was still studying in college. I was interested in exploring all options (I still am!) and then choosing (and sticking to) the best one (I no longer do though!) so I played with Redhat from version 6 to 9 and then Fedora. I also tried a few other distros. My experiments showed me that Linux is in general way too fat for my desktop machine, besides, I had to fight with they system to get it to work the way I wanted it, in comparison Windows was flying like a free bird (!) and drivers were easy to install. Moreover, Windows had applications with MUCH higher quality. (apart from a consistent, fast, and responsive GUI, I recall the pleasant experience of JetAudio, sharp and vivid colours of PowerDVD, excellent games when I was a regular user and then quality of Visual Studio IDE along with a comprehensive offline version of MSDN.) I chose Microsoft because they had the best quality software.
Fast forward 11 years and same is the reason to move to Linux. Ubuntu just worked even before installing! (Live CD) In fact I was listening to a great song while installing it on my main machine! There were zero issues with drivers. (Actually, I didn't install anything!) and best of all, nearly all the applications I have been using are open source and have a version on Linux and to install them, I don't need to head to tens of websites; there's a repository much like Google Play app store but for desktop. GUI is not as good as Windows but after experiencing Windows 10, I can say it's even more consistent than Windows now! And, FORTUNATELY for me, everything is not flat here!
The only missing things are VisualStudio and Photoshop, however, there's VirtualBox in the app repository.
It's hard to believe an OS with this quality is free. I used to laugh at Apple fans because they have been spending ridiculous amounts of money over cr@ppy products, yet wasn't able to see my own bias towards Microsoft. Don't get me wrong, Microsoft was the best software company in the world. (In fact I have always dreamed of working at Microsoft, who hasn't right?!) But unfortunately they have lost their position and worse is that they don't seem to decide to go back.
Microsoft has turned their back to some of the best quality and really cool products they have created (like .Net platform and C# and F# languages) in favour of the closed system of Universal apps and an ugly basic interface they call 'minimalistic design', 'modern', 'metro', etc. It's not art. Not every ugly thing someone famous but illiterate has in mind is art. I don't understand why some people think a futuristic GUI is made of flat lines and rectangles? I believe a futuristic GUI is the one that has been evolved over time the way nature works, evolution rather than revolution. Moreover, I am in favour of science over ideology.
But that unfortunately is not all the story. Beneath the GUI, Linux is actually working better than Windows. For one thing, my hard disk LED is now almost always switched off while in Windows it was almost always on. I don't understand why applications and the OS uses hard disk that bad. I know that Linux file system doesn't need de-fragmentation, but it's not like Windows is de-fragmenting all the time, is it? Moreover, how can Linux run this fast? I mean it was ready to work in a fraction of the time Windows 8.1 needs to load to desktop (FAKE load by the way because after a few years past the installation Windows wasn't responsive to even keyboard interrupts minutes after a boot).
I couldn't imagine a day in which Linux become the faster OS with prettier GUI yet that day has arrived.
BTW, if you are a programmer and have a look at the Linux stack, they almost already have "write once - run everywhere"; Python has Kivy, Qt supports Android and iOS, RoboVM (with insanely high performance on Android) does that using Java, and the list continues.
I will certainly continue using Visual Studio because I really love C# and to an extent I like Web Api and MVC (Apart from Identity, it sucks! One of the worst releases from Microsoft) but for most of my tasks I will be using Ubuntu instead of Windows 10. I will sure miss Windows. I wish they get back where they used to be, after all I used to love the company and their products.
Why should we inject dependencies?
Why shouldn't we hide them?!
What is dependency anyway?
Almost everywhere people use IOC containers and DI frameworks to inject dependencies to classes, often by adding all "dependencies" to a class's constructors as parameters. Apparently the rule is that any class we use inside another class is dependency and shall not be instantiated internally but to be provided as constructor parameter (or a property of that class).
The funny thing is that classes themselves have been created with the intention of hiding their states. In fact libraries and modules in programming languages allow us to no longer think about internals of services but to be users of those services. However, when it comes to class composition these days we shouldn't hide ANYTHING!
There's a problem that's been overlooked, IMO, and it's the amount of complexity we accept by introducing these (often) useless flexibilities.
First of all passing dependencies as parameters makes all the layers that need to pass these dependencies to lower layers more coupled to those dependencies of lower level classes! I don't understand how design legends justify this coupling really!
Then comes all sort of solutions for a problem we created ourselves! One common solution is using factories, then when there are a lot of them, use factories of factories. What a mess!
This much complexity is not worth it, IMO.
Unfortunately dependency injection is not the only commandment sent to poor developers by gods of design. Think about it: when was the last time you decided to replace you Domain layer in an app entirely?! When was the last time you could afford it? When was the last time you really went ahead and did that? I am not saying nobody needs that, I'm just saying do we have any valid number/statistics that tells us the real value of the price we pay? On how many project this has been useful and on how many has it been useless extra cost?
Don't get me wrong, I really like layered design but not because of Dependency Inversion principle that allows us create decoupled changeable layers, but because it helps my mind to deal with only one topic inside each layer. It kinda helps me focus on the task at hand.
Dependency injection, however, is not something I can always like. Sometimes I like to hide classes I use inside another class. I prefer no one on higher levels even know how a class is doing what it does!
Playing around with Asp.Net 5 today. It's still not ready and not worth the time that's going to be wasted fighting with the framework. I spent like two hours getting an upgrade to beta 5 to work but was not successful. Apparently there was an issue with DNX versions.
It's fine to have bugs at this point but what's not cool is the fact that for a simple project we have to edit 2 files as well as the project properties to set the target .Net framework version, moreover, all the three version must match. (Even though in my case VS couldn't find a beta5 of Core framework).
IMO, it's a serious design issue that the version is going to be read from 3 sources.
Decided to install VS 2015 RC in a virtual machine, OS has to be at least Win 8.1. Win 8.1 must have update 1, BTW. While trying to install Windows8.1-KB2919355-x64 I got an error message indicating nothing!
"This update is not applicable to your computer"
Event viewer didn't provide any clue either. It turned out that this KB is dependent to another KB: Windows8.1-KB2919442-x64. After installing the dependency it all went fine.
Note to self: all application errors must guide user what to do. General errors aren't helpful.
Node, knockout, Angular, mean stack, Meteor, and many many more similar yet different frameworks what to choose?!! What should I learn? Is .Net dying? AM I outdated? Should we switch?
My opinion: relax! It's mostly hype!!
Here's the thing: there are server and clients. Clients are now much broader in type. (There used to be only desktop and browser, now we have all sorts of devices like Hololens, bands, glasses, watches, who knows what's next!). So it is getting more and more important to share code because some people aren't willing to write a new project for each device. Many consider it expensive to support multiple codebases. It is also preferred by many to share not just the code between multiple clients but also code between server and client. At least validation codes can be shared.
Best of all, with Asp.Net 5, we ca finally deploy independent from the version of the framework installed on server. .Net framework will be part of our deployed project. How cool is that?! It means we can host our Asp.Net server on a Linxu machine!! I have read that there will soon be good news about performance improvements as well.
I won't switch.
I am very happy with C# and .Net and I am going to invest even further and read more books to give proper depth to my knowledge. I have tried quitting and the results haven't been winning.
I wish there were 5 buttons instead of three for every window in Windows; Close, Restore, Minimize, Minimize to Tray, z-index button or control (keep a window in front or bring it to the front, etc.).
Moreover, I wish there was a way to reopen the window I just mistakenly closed, cause let's face it, the Taskbar is kinda similar to Tab control (BTW, IMHO, Firefox has created the best solution for opening many of them simultaneously, restoring them (Ctrl+Shift+T), etc.)
In fact, I have recently used file explorer in Ubuntu and it's cool to have a tab control for that too per every open window. Cool ideas, not Modern style perhaps but very usable.
Services need to be more aware of each other. In my mobile, for example, I have a list of SMS messages, a list of contacts, multiple apps for email, socialization, etc. Can I find answer to this question while I have all related data: "With which contact of mine am I communicating the most?"? No!
Data of all these apps are separated and these apps won't communicate; even in unified platforms like MS Windows. I believe if our apps could communicate more effectively, we could have a much richer experience. Imagine I could ask my phone to go through all the history I've had with some contact person in all my apps, in any form, and search content of all of them for a specific phrase.
Imagine a statistics app could communicate with all these other apps and count for me how long have I spent with each friend of mine or what are we often talking about, i.e. what are our interests or cool stuff like that.
Imagine an app that could tell me what am I doing with my life by showing me a pie chart of the amount of time I spent on each of my digital activities.
Imagine what a fully connected software world could provide humans...
Apparently $.connection.MyHub was null. $.connection was all good, but the hub wasn't there; generated Hubs.js did not contain any proxies, but why?
I tried almost everything I could find on-line, nothing worked. I enabled logging and saw this in my browser Console:
"Failed to load resource: the server responded with a status of 500 (Internal Server Error)"
Default .Net configuration framework is not good, IMO, because it pushes us to have one file per project, but then when it comes to libraries we aren't allowed to have one per library because libraries won't load any configuration file.
The result is often mess in most projects I have faced. Some settings are duplicated in multiple projects, some go a long way (through a set of layers and classes) to reach their destination. Moreover, updating settings file (let's say the app has a new feature that requires adding new items to user settings file) is a big trouble (I have even spotted strange uncertain behaviors); besides, it can be located in multiple directories which makes updating the file manually a nightmare.
I took a different approach in two projects recently. I created one "Settings" project for my solution and forbid adding any "settings" file to any individual project. Any other project that needed to load/save settings had to add a reference to this new "Setting" project.
To make it easier to access settings I created kind of a Service Locator in this project called "SettingsMan" which can load any of the requested settings like this:
I also used Nini to have an "ini" as my setting file. The end result is much better structured and cleaner code.
Enjoying from reading design books and many online (and even offline in books) debates, I was wondering which of the following is a better design?
if ((new Username("AUsername")).IsValid())...
if ((new UsernameValidator).IsValid("AUsername"))...
if ((new UsernameValidator("AUsername")).IsValid())...
Or this one:
if ((new SupportedCountries).Contains("Canada"))...
if (Countries.Where(x=>string.IsEqual(x.Name, "Canada")).IsSupported)...
As far as opinions are the driving force in this field we wouldn't see a real improvement. I believe, design, more than a new book or article, requires real scientific research.
Last Visit: 11-Dec-18 6:41 Last Update: 11-Dec-18 6:41