Żeby coś było rozszerzalne musisz wiedzieć jak to będzie rozszerzane. Jeśli robisz coś pierwszy raz to po prostu tego nie wiesz.
Takie rzeczy przychodzą z doświadczeniem.
I to należałoby napisać pogrubioną czcionką.
Sam często popadam w dwie skrajności - albo robię coś nieelastycznego i popadam w pewnym momencie w ścianę (zmiany są bardzo ciężkie do wprowadzenia), albo robię coś z założenia superelastycznego, czego efektem jest przekombinowanie i nadmierna złożoność.
W obydwu przypadkach kończy się zwykle przepisywaniem wszystkiego albo części aplikacji od nowa, już lepiej (czyli albo bardziej elastycznie, albo bardziej prosto).
Kiedyś uważałem się za kiepskiego programistę z ww. powodów, ale kiedy zobaczyłem komercyjne i open source'owe projekty, które mają te same wady, co moje programy (czyli albo są za mało elastyczne, albo są przekombinowane), przestałem się uważać za kiepskiego. Szczególnie, kiedy widzę że mnóstwo projektów ma tak kiepski design, że je przepisują na nowo (choćby Angular 2).
Nawet jak ktoś pracuje w Google i ma doświadczenie to nie znaczy wcale, że będzie umiał zrobić zaawansowany framework. Każdy projekt jest inny tak naprawdę, inne założenia, inne wymagania, innego rodzaju problemy które programiści spotkają na swojej drodze. Nawet jak się jest doświadczonym programistą to ciągle spotyka się nowe problemy, które wymagają innego podejścia, ciągle trzeba robić kompromisy (jeśli zrobimy coś w sposób X, to będziemy mieć korzyść Y, ale za to możemy się spotkać z problemem Z, który by nie wystąpił, gdybyśmy zrobili inaczej).
Dlatego wiec programista ciągle się uczy w trakcie tworzenia projektu. Możliwe, że Angulara nie dało się od początku dobrze napisać, i słaby design 1ki był konieczny, żeby wyciągnąć z niego wnioski (mam nadzieję, że wyciągnęli, bo z 2ki jeszcze nie korzystałem).
Dlatego ja jak coś robię to stawiam na robienie działających prototypów na początek, bo prototypy się szybko robi, a każdy zrobiony prototyp to pewnego rodzaju edukacja "co się sprawdza, a co nie". (przez to tracę teoretycznie czas na prototypowanie - ale z drugiej strony ten czas i tak programiści tracą później na przepisywaniu gotowej aplikacji/całych frameworków na nowo. A to zajęłoby więcej czasu).