J-한솔넷

ChatGPT를 이용한 코딩? 본문

프로그래밍/PHP

ChatGPT를 이용한 코딩?

jhansol 2023. 10. 26. 23:51

오늘 매우 간만에 오프라인 교육을 들었습니다.
교육 중에 "ChatGPT를 이용하여 코딩하는 사람이 있다"라는 이야기를 듣고, "그게 가능해?~"라는 의문이 들었습니다. 그래서 집에 돌아와 한번 테스트를 해봤습니다. 아래 내용은 그 결과입니다.

PHP 기반 DTO + Controller + Service + Repository 구조를 가지는 Laravel 프레임워크용 예시 프로그램을 보여줄 수 있어?

물론이죠. Laravel은 PHP 웹 애플리케이션을 빠르게 개발하고 유지보수할 수 있도록 도와주는 인기있는 프레임워크입니다. 아래 예시는 Laravel에서 DTO(Data Transfer Object), Controller, Service, Repository 구조를 구현한 간단한 프로그램입니다.

UserDTO.php

<?php

namespace App\DTO;

class UserDTO
{
    public $name;
    public $email;

    public function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }
}

UserController.php

<?php

namespace App\Http\Controllers;

use App\DTO\UserDTO;
use App\Services\UserService;
use Illuminate\Http\Request;

class UserController extends Controller
{
    protected $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    public function store(Request $request)
    {
        $userDTO = new UserDTO($request->name, $request->email);
        $this->userService->createUser($userDTO);

        return response()->json(['message' => 'User created successfully'], 201);
    }
}

UserService.php

<?php

namespace App\Services;

use App\DTO\UserDTO;
use App\Repositories\UserRepository;

class UserService
{
    protected $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function createUser(UserDTO $userDTO)
    {
        return $this->userRepository->create($userDTO);
    }
}

UserRepository.php

<?php

namespace App\Repositories;

use App\DTO\UserDTO;
use App\Models\User;

class UserRepository
{
    public function create(UserDTO $userDTO)
    {
        $user = new User();
        $user->name = $userDTO->name;
        $user->email = $userDTO->email;
        $user->save();

        return $user;
    }
}

이는 간단한 예시이지만, Laravel에서 DTO, Controller, Service, Repository를 어떻게 구현할 수 있는지를 보여줍니다. 주의할 점은 네임스페이스와 클래스 이름을 적절하게 설정하는 것이며, 이는 실제 프로젝트에서 규모가 확장될 때 더욱 중요해집니다.

UserRepository를 eloquent model로 대체할 수 있어?

네, 물론입니다. 일반적으로 Repository는 데이터베이스와의 상호 작용을 추상화하는 데 사용됩니다. Laravel에서 Eloquent ORM은 데이터베이스와의 상호 작용을 추상화하는 강력한 방법을 제공합니다. 따라서 UserRepository를 Eloquent Model로 대체할 수 있습니다.

예를 들어, UserRepository를 Eloquent Model로 대체한 코드는 다음과 같을 수 있습니다.

UserService.php

<?php

namespace App\Services;

use App\DTO\UserDTO;
use App\Models\User;

class UserService
{
    public function createUser(UserDTO $userDTO)
    {
        return User::create([
            'name' => $userDTO->name,
            'email' => $userDTO->email,
        ]);
    }
}

이렇게 하면 UserRepository 클래스를 사용하지 않고도 Eloquent의 내장 기능을 사용하여 데이터베이스와 상호 작용할 수 있습니다. 이렇게 하면 코드가 간단해지고 읽기 쉬워질 수 있습니다.

UserService 를 ServiceProvidor를 이용하여 의존성 주입 기법으로 변경해줘

서비스 프로바이더를 사용하여 의존성 주입을 설정하면 코드의 유지 보수성과 테스트 용이성을 향상시킬 수 있습니다. Laravel에서는 서비스 프로바이더를 사용하여 의존성을 주입할 수 있습니다. 아래는 UserService를 서비스 프로바이더를 통해 의존성 주입으로 변경하는 예시입니다.

UserService.php

<?php

namespace App\Services;

use App\DTO\UserDTO;
use App\Models\User;

class UserService
{
    public function createUser(UserDTO $userDTO)
    {
        return User::create([
            'name' => $userDTO->name,
            'email' => $userDTO->email,
        ]);
    }
}

UserServiceServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\UserService;

class UserServiceServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(UserService::class, function ($app) {
            return new UserService();
        });
    }
}

그리고 config/app.php 파일에 서비스 프로바이더를 등록해야 합니다.

'providers' => [
    // ...
    App\Providers\UserServiceServiceProvider::class,
],

이제 UserService를 사용할 때, 의존성 주입을 통해 해당 서비스를 받아올 수 있습니다.

$userService = app(UserService::class);
$userService->createUser($userDTO);

URL의 쿼리스티링이 "order=name&direction=asc&field=name&operator=like&keyword=abc&page=1&page_per_items=50" 주어졌을 때 이 내용을 분석하여 보관하는 Laravel용 객체로 프로그램해줄 수 있어?

당연히 가능합니다. 주어진 쿼리 문자열을 분석하여 관련 데이터를 저장하는 객체를 만들 수 있습니다. 아래는 Laravel에서 이러한 작업을 처리하는 예시입니다.

<?php

namespace App;

class QueryData
{
    public $order;
    public $direction;
    public $field;
    public $operator;
    public $keyword;
    public $page;
    public $page_per_items;

    public function __construct($query)
    {
        $this->order = $query['order'] ?? null;
        $this->direction = $query['direction'] ?? null;
        $this->field = $query['field'] ?? null;
        $this->operator = $query['operator'] ?? null;
        $this->keyword = $query['keyword'] ?? null;
        $this->page = $query['page'] ?? null;
        $this->page_per_items = $query['page_per_items'] ?? null;
    }
}

// 사용 예시
$queryString = "order=name&direction=asc&field=name&operator=like&keyword=abc&page=1&page_per_items=50";
parse_str($queryString, $queryArray);
$queryData = new QueryData($queryArray);

// 객체의 값 확인
var_dump($queryData);

이렇게 하면 주어진 URL 쿼리 문자열에서 파싱된 데이터가 QueryData 객체에 저장됩니다. 이 객체를 사용하여 해당 데이터에 접근할 수 있습니다. 이렇게 하면 코드를 더 구조화하고 읽기 쉽게 만들 수 있습니다.

QueryData 객체를 ServiceProvidor를 이용하여 의존성 주입 기법으로 변경해줘

서비스 프로바이더를 사용하여 QueryData 객체를 의존성 주입으로 변경할 수 있습니다. 이를 위해 서비스 프로바이더를 등록하고 의존성 주입을 설정해야 합니다. 아래는 이를 수행하는 예시입니다.

QueryData.php

<?php

namespace App;

class QueryData
{
    public $order;
    public $direction;
    public $field;
    public $operator;
    public $keyword;
    public $page;
    public $page_per_items;

    public function __construct($query)
    {
        $this->order = $query['order'] ?? null;
        $this->direction = $query['direction'] ?? null;
        $this->field = $query['field'] ?? null;
        $this->operator = $query['operator'] ?? null;
        $this->keyword = $query['keyword'] ?? null;
        $this->page = $query['page'] ?? null;
        $this->page_per_items = $query['page_per_items'] ?? null;
    }
}

QueryDataServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\QueryData;

class QueryDataServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(QueryData::class, function ($app) {
            $queryString = request()->getQueryString();
            parse_str($queryString, $queryArray);
            return new QueryData($queryArray);
        });
    }
}

그리고 config/app.php 파일에 서비스 프로바이더를 등록해야 합니다.

'providers' => [
    // ...
    App\Providers\QueryDataServiceProvider::class,
],

이제 의존성 주입을 통해 QueryData를 사용할 수 있습니다.

$queryData = app(QueryData::class);
// 이후에 $queryData 객체를 사용할 수 있습니다.

이렇게 하면 QueryData를 의존성 주입으로 처리하여 객체를 효율적으로 관리할 수 있습니다.

UserController에 사용자 목록을 출력하는 코드를 index라는 메소드로 작성하고 QueryData를 의존성 주입으로 index 메소드의 파레메터로 전달해줘

아래는 UserController에서 사용자 목록을 출력하는 index 메소드를 작성하고 QueryData를 의존성 주입으로 전달하는 방법입니다.

UserController.php

<?php

namespace App\Http\Controllers;

use App\Services\UserService;
use Illuminate\Http\Request;
use App\QueryData;

class UserController extends Controller
{
    protected $userService;
    protected $queryData;

    public function __construct(UserService $userService, QueryData $queryData)
    {
        $this->userService = $userService;
        $this->queryData = $queryData;
    }

    public function index()
    {
        // 사용자 목록을 가져오는 코드 예시
        $users = $this->userService->getUsers($this->queryData);
        // 이후에 $users를 뷰에 전달하여 출력하거나 다른 작업을 수행할 수 있습니다.

        // 예시로서 여기서는 배열을 반환하도록 합니다.
        return ['users' => $users];
    }
}

이 코드는 UserController에서 index 메소드를 사용하여 사용자 목록을 출력하고 있습니다. QueryData를 의존성 주입으로 전달하여 사용자가 요청한 필터링 된 데이터를 사용하여 적절한 사용자 목록을 가져올 수 있습니다.

UserService 클레스에 getUsers 메소드를 작성해줘

아래는 UserService 클래스에 getUsers 메소드를 작성하는 예시입니다.

<?php

namespace App\Services;

use App\Models\User;
use App\QueryData;

class UserService
{
    public function getUsers(QueryData $queryData)
    {
        $query = User::query();

        if ($queryData->field && $queryData->operator && $queryData->keyword) {
            $query->where($queryData->field, $queryData->operator, $queryData->keyword);
        }

        if ($queryData->order && $queryData->direction) {
            $query->orderBy($queryData->order, $queryData->direction);
        }

        if ($queryData->page && $queryData->page_per_items) {
            return $query->paginate($queryData->page_per_items);
        } else {
            return $query->get();
        }
    }
}

실험 후 느낀 점

우선 ChatGPT를 단편적으로만 이용하다 위와 같이 질문하고, 여러 차래 반복 요청하여 코드를 다듬어 본 일이 없었던 저의 입장으로는 "오~ 놀아운데~ 하지만~"으로 요약할 수 있을 듯 합니다. 초창기에는 코드를 복사/붙여넣기한 것으로 보여 참고용으로만 활용했었습니다.
하지만 오늘의 테스트로 나름데로 가이드를 해 줄 수 있을 정도로 코드를 작성해주는 것 같습니다. 물론 위와 같이 여러 차래 변경 요구를 해야겠지만요.
현재로서는 딱 가이드용으로만 활용할 듯 합니다. 완성도 있는 기능 구현 욕심은 아직 금물(만구 저의 생각입니다.)

'프로그래밍 > PHP' 카테고리의 다른 글

삽질의 연속  (1) 2024.04.20
메모리 프로파일링?  (0) 2023.11.09
WSL2를 쓰야하나!!!  (0) 2023.09.14
나의 API 문서화 전략  (0) 2023.09.11