<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Jaemin  Chung on Medium]]></title>
        <description><![CDATA[Stories by Jaemin  Chung on Medium]]></description>
        <link>https://medium.com/@garbagramer?source=rss-7e4385a4b99a------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*QOeFfetU8zTHxAgY.</url>
            <title>Stories by Jaemin  Chung on Medium</title>
            <link>https://medium.com/@garbagramer?source=rss-7e4385a4b99a------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 10:15:54 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@garbagramer/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Goodbye! Object-oriented programming]]></title>
            <link>https://medium.com/@garbagramer/%EC%9B%90%EA%B8%80-7657abefd151?source=rss-7e4385a4b99a------2</link>
            <guid isPermaLink="false">https://medium.com/p/7657abefd151</guid>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Jaemin  Chung]]></dc:creator>
            <pubDate>Tue, 09 Oct 2018 23:22:58 GMT</pubDate>
            <atom:updated>2018-11-08T07:12:27.770Z</atom:updated>
            <content:encoded><![CDATA[<p>Goodbye! Object-oriented programming</p><p>미디엄 프로그래밍 섹션에 올라온 글입니다. 좋은 내용 같아서 팀원들과 공유하고 토론할 수 있도록 원글을 번역해 보았습니다. 영어 실력이 부족하다보니 번역 품질이 떨어집니다. 유념하고 읽어 주시기 바랍니다.</p><p>원글링크: <a href="https://medium.com/@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53?source=linkShare-7e4385a4b99a-1539127342">https://medium.com/@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53?source=linkShare-7e4385a4b99a-1539127342</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*cBFSQ9Ytv_D0jwGtpuL5WA.png" /></figure><p>지난 십여년간 Object Oriented 언어로 프로그래밍을 했다. 첫 OO 언어로C++를 사용했었고 그 후 스몰토크를 썼으며 마지막엔 닷넷과 자바를 썼다.</p><p>OO 패러다임을 구성하는 세 기둥인 상속(<strong><em>Inheritance)</em></strong>, 캡술화(<strong><em>Encapsulation)</em></strong>, 그리고 다형성(<strong><em>Polymorphism)</em></strong>이 주는 효용에 열광했다.</p><p>새롭고 흥미로운 패러다임 관점을 접한 사람들 역시 이러한 지혜를 십분 활용하여 일할것이라 믿어 의심치 않았다.</p><p>실제 오브젝트들을 클래스로 맵핑할 생각으로 흥분을 억누를 수 없었고, 모든 월드의 오브젝트들이 제대로 된 자리를 찾아 들어갈 것이라고 기대했다.</p><p><strong>하지만, 모두 잘못된 생각이었다.</strong></p><h4><strong>상속, 무너진 첫 기둥</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/648/1*T2x8IApyIXIs4nNexGryEw.png" /></figure><p>상속은 OO 패러다임 중에서도 가장 큰 이점으로 여겨진다. 계층 구조를 보여주는 간단한 예제들은 모두 논리적으로 타당해 보인다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*o-Mdcrd9B5hTrrQKhcP8yA.png" /></figure><p>그리고 재사용이란 단어는 매일…아니, 매년, 어쩌면 쭉 듣게되는 말이다.</p><p>나는 이 모든 것들을 받아들였고, 새롭게 깨달은 통찰과 함께 개발에 뛰어들었다.</p><h4>Banana Monkey Jungle 문제</h4><p>OO라는 내 마음 속 종교와 함께 문제를 풀기 위해, 클래스 계층 구조를 세우고 코드를 짜기 시작했다. 모든 것들은 문제가 없었다.</p><p>나는 원래 있던 클래스를 상속받아서 재사용 하고야 말겠다는 다짐을 잊지 않고 있었고, 마침내 그 기다리던 순간이 왔다. 새로운 프로젝트가 생겼는데 그곳에 쓸만한 클래스가 지난번 프로젝트에 있었다.</p><p>문제 없어. 재사용이 날 구해줄거야. 내가 할일은 그저 다른 프로젝트에 있는 클래스를 가져와 사용하는거 뿐이야.</p><p>어디보자…음…이 클래스만으론 안되는군. 부모 클래스가 필요하군. 이제 끝인가?</p><p>으…잠깐…부모의 부모가 또 필요해…그리고….우린 모든 부모 클래스가 필요하군. 좋아좋아, 이건 처리했어. 문제 없어!</p><p>훌륭해. 어? 왜 컴파일이 안되지? 아 알았다..이 오브젝트는 다른 오브젝트를 갖고 있군. 그 오브젝트도 넣어야겠네. 좋아, 됐다.</p><p>잠깐…난 이 오브젝트는 필요 없는데. 난 단지 이 오브젝트의 부모 클래스만 필요한데 그 부모의 부모에 포함된 모든 오브젝트들을 포함해야 하고, 또 그 부모의 부모의….</p><p>에휴.</p><p>Erlang을 만든 <strong><em>Joe Armstrong </em></strong>이 남긴 말이 있다.</p><blockquote>객체 지향 언어의 문제는 그들의 보이지 않는 암시적 환경까지 그들을 따라 다니는다는 것입니다. 당신이 원한건 바나나 뿐이지만 실제로 당신이 얻은건 바나나를 들고 있는 고릴라와 정글 전체였다.</blockquote><blockquote>The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.</blockquote><h4>Banana Monkey Jungle 문제 해결법</h4><p>나는 상속 구조를 너무 깊게 만들지 않는 습관을 들여서 해결했다.하지만 상속이 재사용의 키라면, 상속 메카니즘에 어떠한 제약을 두는 것은 재사용의 이점을 제한하지 않을까?</p><p>그렇다면 어떤 방법이 이런 불쌍한 Object-Oriented 프로그래머를 도울 시원한 사이다가 될 수 있을까?</p><p>대리자(delegate)를 포함해서, 이 부분은 나중에 이야기해보자.</p><h4>The Diamond 문제</h4><p>다음 문제는 그 엉망인 모양새는 무시하고라도 다중 상속을 지원하는 언어들이라면 풀리지 않을 숙제이다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/287/1*88yGno_LfU7P26RAHLGHCw.png" /></figure><p>이것이 논리적으로 타당해보일지라도, 대부분의 OO 언어들은 이것을 지원하지 않는다. OO언어로 이것을 지원하는게 어려운 이유는 무엇일까?</p><p>자, 다음의 pseudocode를 상상해보자:</p><pre>Class PoweredDevice {<br>}</pre><pre>Class Scanner inherits from PoweredDevice {<br>  function start() {<br>  }<br>}</pre><pre>Class Printer inherits from PoweredDevice {<br>  function start() {<br>  }<br>}</pre><pre>Class Copier inherits from Scanner, Printer {<br>}</pre><p><em>Scanner</em> 클래스와 <em>Printer</em> 클래스는 <em>start</em>란 함수를 구현한다는 것을 상기하자.</p><p>그러면, 복사기 클래스는 어떤 시작 기능을 상속해야 할까? 스캐너 하나? 프린터 하나? 둘 다 할 순 없다.</p><h4>The Diamond 문제 해결법</h4><p>이것의 해결책은 간단하다. 안하면 된다.</p><p>그래, 맞다. 대부분의 OO언어는 당신이 그렇게 하도록 허락하지 않는다.</p><p>하지만…하지만…이것을 모델링 해야한다면? 난 재사용을 원한다고!!!</p><p>그렇다면 대리자(delegate)를 사용해라.</p><pre>Class PoweredDevice {<br>}</pre><pre>Class Scanner inherits from PoweredDevice {<br>  function start() {<br>  }<br>}</pre><pre>Class Printer inherits from PoweredDevice {<br>  function start() {<br>  }<br>}</pre><pre>Class Copier {<br>  Scanner scanner<br>  Printer printer<br>  function start() {<br>    printer.start()<br>  }<br>}</pre><p><em>Copier </em>클래스는 프린터와 스캐너 인스턴스를 포함하는 것에 유의하라. <em>start</em> 함수는 <em>Printer</em> 클래스의 구현된 <em>start</em>함수를 위임한다. Scanner에도 쉽게 적용할 수 있다.</p><p>이 문제는 상속이라는 기둥의 또다른 크랙이다.</p><h4>The Fragile Base Class 문제</h4><p>이제 나는 내 계층 구조를 얕게 만들었고 주기적으로 관리했다. 다이아몬드 구조는 없다.</p><p>그리고 이제 이 월드는 문제없었다. 아직까지는..</p><p>하루는 내 코드가 동작했고, 다음날은 멈췄다. <strong>나는 코드를 고치지 않았는데 말이다.</strong></p><p>어디보자….이게 버그네. 근데…뭐가 바뀌어 있는데…..</p><p><strong>하지만 그건 내 코드가 아니었다.</strong> 내가 상속한 클래스에서 뭔가 변화가 있었다.</p><p>어떻게 베이스 클래스가 내 코드를 바꿀 수 있는가?</p><p>다음의 베이스 클래스를 보자(Java로 쓰여 있지만, Java를 모르더라도 쉽게 이해할 수 있다):</p><pre>import java.util.ArrayList;<br> <br>public class Array<br>{<br>  private ArrayList&lt;Object&gt; a = new ArrayList&lt;Object&gt;();<br> <br>  public void add(Object element)<br>  {<br>    a.add(element);<br>  }<br> <br>  public void addAll(Object elements[])<br>  {<br>    for (int i = 0; i &lt; elements.length; ++i)<br>      <strong>a.add(elements[i]); // this line is going to be changed</strong><br>  }<br>}</pre><p><strong>중요</strong>: 주석이 달린 라인을 주목하라. 이 라인이 바뀌었고 나중에 다른 코드를 깨트린다.</p><p>이 클래스는 인터페이스에 <strong><em>add()</em></strong> 와 <strong><em>addAll() </em></strong>함수를 갖는다. <strong><em>add()</em></strong> 함수는 하나의 element를 추가하고, <strong><em>addAll() </em></strong>함수는 다수의 elements를 <strong>add함수를 이용하여 ArrayList에 추가한다.</strong></p><p>그리고 여기 상속받은 클래스가 있다:</p><pre>public class ArrayCount extends Array<br>{<br>  private int count = 0;<br> <br>  <a href="http://twitter.com/Override">@Override</a><br>  public void add(Object element)<br>  {<br>    super.add(element);<br>    ++count;<br>  }<br> <br>  <a href="http://twitter.com/Override">@Override</a><br>  public void addAll(Object elements[])<br>  {<br>    super.addAll(elements);<br>    count += elements.length;<br>  }<br>}</pre><p>ArrayCount클래스는 general array 클래스를 처리할 수 있게 구현되어있다. 유일한 다른 점은 ArrayCount는 elemente들의 숫자를 카운트해서 들고 있다는 것 뿐이다.</p><p>여기 두 클래스를 자세히 살펴보자.</p><p><strong><em>Array</em></strong>의 add()는 local <strong><em>ArrayList</em></strong>에 element를 추가한다.<br><strong>Array</strong>의 addAll() 은 local <strong>ArrayList</strong>의 각 element를 추가한다.</p><p><strong><em>ArrayCount</em></strong>의<em> </em><strong><em>add()</em></strong>는 부모의 <strong><em>add()</em></strong>를 호출하고 <strong><em>count</em></strong>를 증가시킨다.<br><strong>ArrayCount</strong>의 <strong><em>addAll()</em></strong> 는 부모의 <strong><em>addAll()</em></strong>를 호출하고 elements의 숫자만큼 <strong><em>count</em></strong>를 증가시킨다.</p><p>모두 잘 동작한다.</p><p>코드가 갑자기 바뀌었다. 베이스 클래스의 주석이 달렸던 라인이 다음과 같이 바뀌었다:</p><pre>public void addAll(Object elements[])<br>  {<br>    for (int i = 0; i &lt; elements.length; ++i)<br>      <strong>add(elements[i]); // this line was changed</strong><br>  }</pre><p>베이스 클래스를 소유한 클래스가 관련된 경우, 의도대로 동작한다. <strong>그리고 모든 자동 테스트도 여전히 통과된다.</strong></p><p>그러나 파생 클래스까지에 미치는 변화까지는 인식하지 못한다. 그리고 파생 클래스를 소유한 클래스의 경우 멍청한 계산을 하게 된다.</p><p><strong><em>ArrayCount</em></strong>의<strong><em> addAll()</em></strong> 는 부모의 <strong><em>addAll()</em></strong> 를 호출하고 <strong>내부적으로</strong> 자식에서 override된 <strong><em>add()</em></strong>를 호출한다.</p><p>그 결과로 <strong><em>count</em></strong>값이 자식 클래스의 <strong><em>add()</em></strong>에서 증가하게 되고 AddAll()함수에서 element들의 숫자에 따라 한번 더 더해지게 된다.</p><p>두 배로 카운트 되는 것이다.</p><p>만약 이런일이 발생하면, 모든 자식클래스를 구현한 사람들은 베이스 클래스가 어떻게 구현되었는지 알아야 한다. 그리고 그들이 예측할 수 없는 방식으로 파생 클래스를 깨트릴 수 있기 때문에 베이스 클래스의 모든 변화에 대해 알아야 한다.</p><p>에휴! 이 엄청난 크랙은 영원히 귀중한 상속이라는 기둥의 안전성을 위협할 것이다.</p><h4>The Fragile Base Class 문제 해결법</h4><p>다시 한번, 대리자를 클래스에 포함시키고 이것을 써서 해결하자.</p><p>대리자를 사용함으로써, 화이트 박스 프로그래밍에서 블랙 박스 프로그래밍으로 갈 수 있다. 화이트 박스 프로그래밍은 베이스 클래스의 구조를 보고 있어야만 한다.</p><p>블랙박스 프로그래밍에선 완전히 내부 구현을 몰라도 된다. 그 이유는 베이스 클래스의함수들을 overriding을 통해 삽입할 수 없기 때문이다. 인터페이스만 신경을 쓰면 된다.</p><p>이 트렌드는 좀 번거롭다…</p><p>상속은 재사용을 통해 패러다임의 승자로 여겨졌다.</p><p>OO 언어는 쉽게 대리자를 포함시키고 만들 수 없다. 이런 언어는 상속을 쉽게 하기 위해 디자인되어 있다.</p><p>당신은 나처럼 이 상속이란 기능에대해 의문을 품기 시작했을 것이다. 그러나 더욱 중요한 것은, 계층 구조를 통한 클래스 분류의 위력에 대한 믿음이 흔들린다는 것이다.</p><h4>The Hierarchy Problem</h4><p>새로운 회사에서 시작할때마다, 회사용 문서(e.g.직원 핸드북)를 작성할 곳을 찾기가 어려웠다.</p><p>문서라는 폴더를 만들고, 회사라는 폴더를 만듭니까?<br>아니면 회사라는 폴더를 만들고 문서라는 폴더를 만듭니까?</p><p>둘 다 동작한다. 하지만 어떤것이 맞는가? 어떤 것이 더 좋은가?</p><p>카테고리로 구분한 계층도(Categorical Hierarchies)의 아이디어는 기본 클래스(부모)는 좀 더 일반적이고, 이러한 속성을 갖는 클래스 들 중 몇몇 부분이 더 특화된 버전이 파생 클래스(자식)로 두는 것이다. 그리고 거기서 더욱 특화된 버전으로 체인이 이어진다. (상단의 Shape Hierarchy를 보라)</p><p>하지만 부모와 자식의 위치를 임의적으로 바꿀 수 있다면, 이 모델은 명백히 잘못된 것이다.</p><h4>The Hierarchy 해결법</h4><p>뭐가 잘못된 것이냐면…</p><p><strong>계층도가 제대로 동작하지 않는 다는 것이다.</strong></p><p>그럼 계층도는 어디에 쓸 수 있을까요?</p><p><strong>Containment</strong>.</p><p>If you look at the real world, you’ll see Containment (or Exclusive Ownership) Hierarchies everywhere.</p><p>What you won’t find is Categorical Hierarchies. Let that sink in for a moment. The Object Oriented Paradigm was predicated upon the real world, one filled with Objects. But then it uses a broken model, viz. Categorical Hierarchies, where there is no real-world analogy.</p><p>But the real world is filled with Containment Hierarchies. A great example of a Containment Hierarchy is your socks. They are in a sock drawer which is contained in one drawer in your dresser which is contained in your bedroom which is contained in your house, etc.</p><p>Directories on your hard drive are another example of a Containment Hierarchy. They contains files.</p><p>So how do we categorize then?</p><p>Well, if you think of the Company Documents, it pretty much doesn’t matter where I put them. I can put them in a folder of Documents or a folder called Stuff.</p><p>The way I categorize it is with tags. I tag the file with the following tags:</p><pre>Document<br>Company<br>Handbook</pre><p>Tags have no order or hierarchy. (This solves the Diamond Problem too.)</p><p>Tags are analogous to interfaces since you can have multiple types associated with the document.</p><p>But with so many cracks, it looks like the Inheritance pillar has fallen.</p><p><strong>Goodbye, Inheritance.</strong></p><h3>Encapsulation, the Second Pillar to Fall</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/648/1*ta9gcTzwC_RxZxvD7EhlAw.png" /></figure><p>At first glance, Encapsulation appears to be second biggest benefit of Object Oriented Programming.</p><p>Object state variables are protected from outside access, i.e. they’re Encapsulated in the Object.</p><p>No longer will we have to worry about global variables that are being accessed by who-knows-who.</p><p>Encapsulation is a Safe for your variables.</p><p>This Encapsulation thing is INCREDIBLE!!</p><p>Long live Encapsulation…</p><p>That is until…</p><h4>The Reference Problem</h4><p>For efficiency sake, Objects are passed to functions NOT by their value but by reference.</p><p>What that means is that functions will not pass the Object, but instead pass a <strong><em>reference</em></strong> or pointer to the Object.</p><p>If an Object is passed by reference to an Object Constructor, the constructor can put that Object reference in a private variable which is protected by Encapsulation.</p><p>But the passed <strong>Object is NOT safe!</strong></p><p>Why not? Because some other piece of code has a pointer to the Object, viz. the code that called the Constructor. It MUST have a reference to the Object otherwise it couldn’t pass it to the Constructor?</p><h4>The Reference Solution</h4><p>The Constructor will have to Clone the passed in Object. And not a shallow clone but a deep clone, i.e. every object that is contained in the passed in Object and every object in those objects and so on and so on.</p><p>So much for efficiency.</p><p>And here’s the kicker. Not all objects can be Cloned. Some have Operating System resources associated with them making cloning useless at best or at worst impossible.</p><p>And <strong>EVERY</strong> single mainstream <strong>OO language</strong> has this problem.</p><p><strong>Goodbye, Encapsulation.</strong></p><h3>Polymorphism, the Third Pillar to Fall</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PgDq0T-0PpSd-huvTaZxkw.png" /></figure><p>Polymorphism was the redheaded stepchild of the Object Oriented Trinity.</p><p>It’s sort of the Larry Fine of the group.</p><p>Everywhere they went he was there, but he was just a supporting character.</p><p>It’s not that Polymorphism isn’t great, it’s just that you don’t need an Object Oriented language to get this.</p><p>Interfaces will give you this. And without all of the baggage of OO.</p><p>And with Interfaces, there isn’t a limit to how many different behaviors you can mix in.</p><p>So without much ado, we say goodbye to <strong>OO</strong> Polymorphism and hello to <strong>interface-based</strong> Polymorphism.</p><h3>Broken Promises</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/648/1*BKqtA-ynElomtJ7v6n5FHw.png" /></figure><p>Well, OO sure promised a lot in the early days. And these promises are still being made to naive programmers sitting in classrooms, reading blogs and taking online courses.</p><p>It’s taken me years to realize how OO lied to me. I too was wide-eyed and inexperienced and trusting.</p><p>And I got burned.</p><p><strong>Good-bye, Object Oriented Programming.</strong></p><h3>So then what?</h3><p>Hello, <strong>Functional Programming</strong>. It’s been so nice to work with you over the past few years.</p><p>Just so you know, I’m NOT taking any of your promises at face value. I’m going to have to see it to believe it.</p><p><strong>Once burned, twice shy and all.</strong></p><p>You understand.</p><p><em>If you liked this, click the💚 below so other people will see this here on Medium.</em></p><p>If you want to join a community of web developers learning and helping each other to develop web apps using Functional Programming in Elm please check out my Facebook Group, <strong><em>Learn Elm Programming</em></strong><a href="https://www.facebook.com/groups/learnelm/">https://www.facebook.com/groups/learnelm/</a></p><p>My Twitter: <a href="https://twitter.com/cscalfani">@cscalfani</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7657abefd151" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>