좋은 코드, 나쁜 코드

25669 단어 advicevideocode
이 비디오에서 나는 다시 한 번 좋은 코드에 대한 아이디어로 돌아옵니다. 좋은 코드의 4가지 특징을 예제와 함께 제시하고 코드 작성이나 리뷰를 마치면서 항상 하는 3가지 질문에 대해 이야기합니다.



메모



소개



몇 에피소드 전에 저는 좋은 코드의 개념에 대해 이야기했습니다. 좋은 코드의 4가지 특징을 설명했습니다. 그런 다음 에피소드 4에서 코드의 가독성을 향상시킬 수 있는 몇 가지 간단한 기술을 보여주었습니다. 오늘 다시 좋은 코드에 대해 이야기하고 잘 설계된 코드의 몇 가지 특성에 초점을 맞출 것입니다. 각 특성에 대해 몇 가지 예를 보여주고 해당 코드를 개선하는 방법을 설명하겠습니다.

솔직한


  • 정직한 사람은 진실을 말하고(거짓말하지 않고) 전체 진실을 말하는 사람입니다(일부 숨기지 않음)
  • 정직한 코드는 거짓말을 하지 않습니다(예: 실제로 사용자를 삭제하는 "createUser"라는 메서드는 거짓말입니다)
  • 정직한 코드는 진실을 숨기지 않습니다.

  • class User
      def self.find(id)
        user = @users.detect { |user| user.id == id }
        return user || self.new()
      end
    end
    
    class User
      def self.find(id)
        return @users.detect { |user| user.id == id }
      end
    end
    
    User.find(id) || User.new()
    
    class User
      def self.find_or_new(id)
        user = @users.detect { |user| user.id == id }
        return user || self.new()
      end
    end
    



    class Http {
      public static function get(url, filter = null) {
        return fetch(url)
          .then((resp) => resp.json())
          .then((json) => filter ? filter(json) : json);
      }
    }
    
    class Http {
      public static function get(url, filter = null) {
        return fetch(url) 
          .then((resp) => resp.json())
      }
    }
    
    Http.get("<http://someurl.com>").then((json) => filterData(json));
    
    class Http {
      public static function getAndFilter(url, filter = null) {
        return fetch(url)
          .then((resp) => resp.json())
          .then((json) => filter ? filter(json) : json);
      }
    }
    



    class User {
      public allUsers;
    
      public static function create(email, password) {
        return User.allUsers[0];
      }
    }
    


    간결한


  • 좋은 코드는 불필요하게 길면 안 됩니다.
  • 항상 그렇듯이 여기에는 균형이 있으므로 코드를 이해하기 쉽게 만드는 것이 요점입니다.
  • 너무 짧을 수 있는 코드:
  • 200자 한 줄이면 아마 이해하기 쉽지 않을 것입니다.
  • 두문자어를 사용하는 변수
  • 코드가 너무 길 수 있음
  • 새 변수를 사용하여 모든 작업을 별도의 줄에 작성

  • <?php
    
    function totalPrice($order)
    {
        $items = $order->items;
        $items = new Collection($items);
        $prices = $items->map(function($item) { return $item->price * $item->count });
        $totalPrice = $prices->reduce(function($total, $price) {
            return $total + $price;
        }, 0);
        return $totalPrice;
    }
    
    <?php
    
    function totalPrice($order)
    {
        return (new Collection($order->items))
            ->map(function($item) { return $item->price * $item->count })
            ->reduce(function($total, $price) { return $total + $price; }, 0);
    }
    
    
    <?php
    
    function totalPrice($order)
    {
        return (new Collection($order->items))
            ->reduce(function($total, $item) {
                return $total + ($item->price * $item->count)
            }, 0);
    }
    
    


    눈에 거슬리지 않는


  • 코드는 코드와 직접적으로 관련이 없는 장소에 영향을 미쳐서는 안 됩니다.
  • 변경 사항은 작업 중인 레이어로 제한되어야 합니다
  • .
  • 예:
  • 모델 계층에서 HTTP 경로 생성
  • 템플릿에서 데이터베이스 쿼리 실행

  • class UserController {
    
       public handleRequest(request: Request): View {
         return User.handle(request);
       }
    
     }
    
     class User {
    
       public static handle(request: Request): View {
         if (request.method === "POST") {
           user = User.create(request.parameters);
           return new View("createUser", user);
         } else {
           user = User.find(request.query["id"]);
           return new View("showUser", user);
         }
       }
    
       public static create(parameters: any) {
         // TODO
       }
    
       public static find(id: number) {
         // TODO
       }
    
     }
    
    
    class UserController {
    
      public handleRequest(request: Request): View {
        if (request.method === "POST") {
          return this.handlePostRequest(request);
        } else {
          return this.handleGetRequest(reqeust);
        }
      }
    
      private handleGetRequest(request: Request): View {
        user = User.find(request.query["id"]);
        return new View("showUser", user);
      }
    
      private handlePostRequest(request: Request): View {
        user = User.create(this.filteredParameters(request.parameters));
        return new View("createUser", user);
      }
    
      private filterRequestParameters(parameters: any) {
        // TODO
      }
    
    }
    
    class User {
    
      public static create(parameters: any) {
        // TODO
      }
    
      public static find(id: number) {
        // TODO
      }
    
    }
    
    


    일관된


  • 애플리케이션이 작동하는 방식은 사용자가 기대하는 방식이어야 합니다
  • .
  • 코드에도 동일하게 적용되며 개발자가 기대하는 방식과 방식으로 작동해야 합니다.
  • 일관성 없는 코드가 그 가정을 깨뜨림
  • 일관성은 이름 지정, 언어 관용구, 동일한 라이브러리 사용 등 다양한 방식으로 나타납니다.
  • 예:

  • class User
      def self.find(id = nil)
        return @users.find { |user| user.id == id }
      end
    end
    
    class Product
      def self.find(id: nil)
        product = @products.find { |p| p.id == id }
        raise NotFoundException unless product
        return product
      end
    end
    
    user = User.find(10) # will return User object or nil
    product = Product.find(id: 20) # will return Product object or raise an error
    
    
    class User
      def self.find(id = nil)
        return @users.find { |user| user.id == id }
      end
    end
    
    class Product
      def self.find(id = nil)
        return @products.find { |p| p.id == id }
      end
    end
    
    user = User.find(10) # will return User object or nil
    product = Product.find(20) # will return Product object or nil
    
    


    스스로에게 물어보세요: 이 코드는 수정하기 쉬운가요?


  • 개발자로서 우리는 종종 우리의 코드가 어떤 시점에서 변경될 것임을 알고 있습니다
  • 우리는 언제, 어떤 방식으로 바뀔지 모릅니다.
  • 다음과 같은 경우 코드를 수정하기 쉽습니다.
  • 이해하기 쉬움 (모르는 것은 바꿀 수 없다)
  • 탐색하기 쉽습니다(찾을 수 없는 것을 변경할 수 없음)
  • 테스트하기 쉬움 (확인할 수 없는 것은 변경할 수 없음)
  • 좋은 웹페이지 즐겨찾기