연습 아그니. - 코드 보여주세요.

내 게시물 이후 많은 사람들이 코드에서 아그니를 연습하는 모습이 어떠냐고 물었다.
간단하게 돌이켜 보면 아그니는 eXtreme Programming의 원칙이다.아그니는 네가 그것의 알파벳 줄임말을 필요로 하지 않는다.
나는 극한 프로그래밍의 공동 창시자 중 한 명인 론 제프리스(Ron Jeffries)가 아그니의 실천을 잘 정리했다고 생각한다.

Implement things when you actually need them, never when you just foresee that you need them.



왜 아그니 연습이 어려워요?
흥미로운 알파벳 줄임말과 간단명료한 요약이 있지만 프로그래머들은 과도한 프로젝트에 굴복하거나 새로운 반짝이는 기술을 실시하거나 다른 기능을 추가하는 경우가 많다.설령 우리가 이러한 충동을 극복했다 하더라도, 우리는 코드에서 아그니를 연습하는 것이 무엇을 의미하는지 여전히 잘 모른다.어쨌든 우리는 프로그래머이기 때문에 코드가 웅변보다 낫다.
라스무스 러도프는 나에게 "비밀번호를 보여줘."라고 말했다.그러므로 나는 본문의 남은 시간 동안 일련의 stories를 연구할 것이다.YAGNI 연습을 통해 코드가 어떻게 자연스럽게 변하는지 타고난 것이 아니라 보게 될 것이다.이 코드 예들은 레도프 씨를 기념하기 위해 PHP로 작성되었다.

첫 번째 사연입니다.

As marketing I want to get a list of all users so I can perform analytics.
Given I access a specific URL
Then I should get a list of all users in JSON format


첫 번째 이야기가 가장 도전적이다.이것은 우리의 욕망이 가장 큰 때다.기억해라, 아그니는 우리에게 우리가 진정으로 필요로 하는 것만 실현하라고 말했다.아니면, 다른 방식으로 말하면, 가능한 한 간단한 것을 써라.
다음은 이 코드들의 모습이다.
<?php
$mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');

$query = 'SELECT * FROM users';
$result = $mysqli->query($query);
$users = $result->fetch_all(MYSQLI_ASSOC);

header('Content-Type: application/json');
echo json_encode(['users' => $users]);
물론 이 코드는 결코 우아하지 않다.Reddit 또는 Stack Overflow에서 거부될 수도 있습니다.The Pragmatic Programmer'충분한 소프트웨어'를 어떻게 만드는지 토론한 것이 바로 본고의 주제이다.부인할 수 없습니다. 7줄 코드만 있으면 간단합니다.어떤 초보 프로그래머든지 이 코드들을 쉽게 사용할 수 있다.가장 중요한 것은 이야기를 완성했다는 것이다.다른 건 없어요.마찬가지로 (기술적으로 우리는 JSON 형식으로 users표를 저장하고 정적 파일을 제공할 수 있었다).

두 번째 사연입니다.

As legal I don't want the user's password to be in the response so we don't get sued.
Given I access the URL for the user list
Then I should get a list of all users in JSON format
And it should not include their password


그러면 우리가 할 수 있는 가장 간단한 일은 무엇입니까?적절한 필드만 선택하여 SQL 쿼리를 조정할 수 있습니다.
<?php
$mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');

$query = 'SELECT email, role FROM users';
$result = $mysqli->query($query);
$users = $result->fetch_all(MYSQLI_ASSOC);

header('Content-Type: application/json');
echo json_encode(['users' => $users]);

세 번째 사연입니다.

As marketing I want to filter the user list by email address so I can group user data more easily.
Given I access the URL for the user list
And I set an "email" parameter
Then I should get a list of all users in JSON format whose email address contains the "email" parameter value


마찬가지로 email 매개 변수에 따라 SQL 쿼리를 조정합니다.
<?php
$mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');

$query = 'SELECT email, role FROM users';
if (!empty($_GET['email'])) {
    $query .= 'WHERE email LIKE \'%' . $_GET['email'] . '%\'';
}

$result = $mysqli->query($query);
$users = $result->fetch_all(MYSQLI_ASSOC);

header('Content-Type: application/json');
echo json_encode(['users' => $users]);
이제 이야기는 끝났지만 우리가 계속 소홀히 해서는 안 될 몇 가지가 있다.

  • 복잡성 증가if 문장은 코드의 새로운 논리 지점을 도입했다.

  • 변화율.최근 기사마다 SQL 문구를 변경해야 합니다.

  • 안전 위험.추가된 코드는 SQL 주입의 공격을 받기 쉽다.
  • 이런 원인들은 반드시 우리가 코드를 재구성하는 것을 지도해야 한다.흔히 볼 수 있는 오해는 YAGNI와 재구성이 서로 대립한다는 것이다.나는 그들의 관계가 더욱 공생하는 것을 발견했다.YAGNI는 나의 코드를 간단하게 유지하고 재구성을 쉽게 한다.만약 나의 코드가 재구성되기 쉽다면, 나는 언제든지 코드를 신속하게 다시 작성할 수 있다.이것은 나로 하여금 간단한 코드를 계속 작성하고 이 순환을 계속할 자신감을 가지게 한다.
    그래서 복잡성을 추출하기 위해 재구성합시다.이 점에서 코드에 대해 더욱 익숙하기 때문에 저장소의 대상은 분명히 후보 대상이다.또한 SQL 주입 위험을 낮추기 위해 저장소를 저장합니다.
    <?php
    require 'vendor/autoload.php';
    
    $mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');
    
    $userRepository = new UserRepository($mysqli);
    $users = $userRepository->getUsers($_GET['email']);
    
    header('Content-Type: application/json');
    echo json_encode(['users' => $users]);
    

    네 번째 사연입니다.

    As marketing I want to see a description for "role" so I can better understand the data.
    Given I access the URL for the user list
    And the user's role is 1 or 2
    Then I should see "Member" or "VIP" (respectively) for "role"


    여러 가지 실현이 있는데, 그 중 두 가지가 곧 머릿속에 떠오를 것이다.우리는 SQL 문에서 실현할 수도 있고 코드로 실현할 수도 있다.SQL 문을 업데이트하는 것은 가장 간단하다고 할 수 있지만 복잡성을 크게 증가시켰다.이 때문에 나는 코드로 그것을 실현하기로 선택했다.
    <?php
    require 'vendor/autoload.php';
    
    $mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');
    
    $userRepository = new UserRepository($mysqli);
    $raw_users = $userRepository->getUsers($_GET['email']);
    
    $users = [];
    foreach ($raw_users as $user) {
        $users = [
            'email' => $user['email'],
            'role' => $user['role'] == 2 ? 'VIP' : 'Member'
        ];
    }
    
    header('Content-Type: application/json');
    echo json_encode(['users' => $users]);
    
    그러나 이 코드는 여전히 유효하다. 새로운 코드 지점과 업무 논리를 도입했다.이것도 우리의 줄 번호를 배로 증가시켰다.따라서 나는 이 간단한 해결 방안을 작성할 때 절약한 시간을 이용해서 더 간단한 선택이 있는지 확인할 것이다.사실 PHP는 JsonSerializable 인터페이스가 있는데 우리는 그것을 실현해서 json_encode()로 값을 되돌릴 수 있다.
    나는 실현User의 간단한 JsonSerializable 대상을 도입하여 새로운 논리를 그곳으로 옮길 수 있다.나는 UserRepository 개 대상의 그룹을 되돌려 주기 위해 User 를 업데이트할 것이다.마지막 코드는 내가 이 이야기를 시작했을 때의 코드와 같아서 성공적인 재구성임을 증명한다.
    <?php
    require 'vendor/autoload.php';
    
    $mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');
    
    $userRepository = new UserRepository($mysqli);
    $users = $userRepository->getUsers($_GET['email']);
    
    header('Content-Type: application/json');
    echo json_encode(['users' => $users]);
    

    다섯째 층

    As Finance I need to get the user list in XML format so we can import it into our archaic systems.
    Given I access the URL for the user list
    And I set my "Accept" header to "application/xml"
    Then I should get a list of all users in XML format


    현재, 당신은 이미 그 중의 비결을 파악했기 때문에, 응답을 바꾸기 위해 if 문장을 추가합니다.
    <?php
    require 'vendor/autoload.php';
    
    $mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');
    
    $userRepository = new UserRepository($mysqli);
    $users = $userRepository->getUsers($_GET['email']);
    
    if (strpos($_SERVER['HTTP_ACCEPT'], 'application/xml') !== false) {
        header('Content-Type: application/xml');
        // output the XML...
    } else {
        header('Content-Type: application/json');
        echo json_encode(['users' => $users]);
    }
    
    우리는 계속 이 길을 따라 걸어갈 수 있지만, 우리는 코드 지점을 다시 도입할 것이다.TDD(XP의 또 다른 핵심 원칙) 테스트를 사용하여 이 코드를 구동하는 경우, 상하문을 추가하여 다른 코드 경로를 테스트할 때 이 점을 알 수 있습니다.우리들은 이 기회를 이용하여 대상을 소개합시다.
    <?php
    require 'vendor/autoload.php';
    
    $mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');
    
    $userRepository = new UserRepository($mysqli);
    $users = $userRepository->getUsers($_GET['email']);
    
    ContentNegotiator::sendResponse($user);
    
    이 예에서 우리는 사용자 데이터를 간단한 내용 협상자에게 전달할 것이다.그것은 심지어 정적일 수도 있다. 왜냐하면 상태가 없기 때문에 응답만 출력할 뿐이다.

    복고적
    연습 아그니가 우리에게 무엇을 주었는지 보여주자.

  • 속도.우리는 아그니가 우리를 집중하게 하기 때문에 다섯 개의 이야기를 빠르게 가볍게 완성했다.

  • 간단하다우리는 실제로 초기 코드의 크기를 줄였다.우리는 필요에 따라 새로운 대상을 도입하여 그것들의 내중성을 높였다.

  • 스트레스 없어요.마지막으로 우리는 스트레스 없이 이 모든 것을 실현했다.우리는 구조나 범위에 대한 우려에 빠지지 않았다.
  • 네가 아그니를 연습하는 것에서 나와 같은 좋은 점을 찾을 수 있기를 바란다.
    더 드릴까요?트위터를 주목하고 매주 인코딩 기교, 지혜로운 전송과 다른 랜덤성을 얻는다.

    좋은 웹페이지 즐겨찾기