-
2주차 주간과제의 키오스크 앱에 작성한 소스코드를 확인하고, 코드 구성과 위젯 구성을 재배치하여 코드를 개선하는 리팩토링을 진행하시오.
- 리팩토링이란, 소프트웨어를 보다 쉽게 이해할 수 있도록 만드는 작업이다.
- 본인의 코드에서 부족했던 점을 개선할 수 있도록 한다.
- 가독성과 유지보수성을 높이는 목표를 가질 수 있도록 한다.
- 기존 코드를 보고 리팩토링이 적용된 핵심코드를 정리하시오.
기존에 했던 코드에서 리팩토링한점,
1. MVC 디자인패턴사용? (Card위젯도 따로 만들어서 관리)
2. 패키지 get사용
main.dart
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:order_app36/controller/main_controller.dart'; import 'package:order_app36/util/app_pages.dart'; import 'package:order_app36/util/app_routes.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return GetMaterialApp( initialBinding: BindingsBuilder(() { Get.put(Maincontroller()); //MainController 전역사용 }), getPages: AppPages.pages, //페이지 관리 initialRoute: AppRoutes.main, //첫페이지 ); } }
lib/controller/main_controller.dart
import 'package:get/get.dart'; import 'package:order_app36/model/menu.dart'; class Maincontroller extends GetxController { RxList order = [].obs; //관측가능한 변수 초기화 final List foodMenu = [ //메뉴모델 데이터저장 Menu(Img: "assets/images/option_bokki.png", name: "떡볶이"), Menu(Img: "as sets/images/option_beer.png", name: "맥주"), Menu(Img: "assets/images/option_kimbap.png", name: "김밥"), Menu(Img: "assets/images/option_omurice.png", name: "오므라이스"), Menu(Img: "assets/images/option_pork_cutlets.png", name: "돈까스"), Menu(Img: "assets/images/option_ramen.png", name: "라면"), Menu(Img: "assets/images/option_udon.png", name: "우동") ]; addOrder(String FoodName) { //mainpage에서 사용될 주문리스트추가함수 order.add(FoodName); } clearOrder() { //mainpage에서 사용될 주문리스트 초기화함수 order.clear(); } }
lib/model/menu.dart
class Menu { String name; String Img; Menu({ required this.name, required this.Img, }); } 메뉴 클래스
lib/util/app_pages.dart
import 'package:get/get.dart'; import 'package:order_app36/util/app_routes.dart'; import 'package:order_app36/view/page/admin_page.dart'; import 'package:order_app36/view/page/main_page.dart'; class AppPages { static final pages = [ GetPage(name: AppRoutes.main, page: () => const MainPage()), GetPage(name: AppRoutes.admin, page: () => const AdminPage()), ]; }
lib/util/app_routes.dart
import 'package:order_app36/view/page/admin_page.dart'; import 'package:order_app36/view/page/main_page.dart'; class AppRoutes { static const main = MainPage.route; static const admin = AdminPage.route; }
lib/view/widget/foodcard.dart
import 'package:flutter/material.dart'; import 'package:order_app36/model/menu.dart'; class MenuCard extends StatelessWidget { const MenuCard({super.key, required this.menu}); final Menu menu; //Menu모델 사용 @override Widget build(BuildContext context) { return Card( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Image( image: AssetImage(menu.Img), width: double.infinity, fit: BoxFit.cover, )), Text( menu.name, style: const TextStyle(fontWeight: FontWeight.bold), ), const Text( '[담기]', style: TextStyle(color: Colors.black), ) ], ), ); } }
lib/view/page/main_page.dart
// ignore_for_file: prefer_const_constructors import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:order_app36/controller/main_controller.dart'; import 'package:order_app36/util/app_routes.dart'; import 'package:order_app36/view/widget/foodcard.dart'; class MainPage extends GetView<Maincontroller> { const MainPage({super.key}); static const String route = '/main'; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: GestureDetector( onDoubleTap: () => Get.toNamed(AppRoutes.admin), child: const Text('분식왕 이테디 주문하기')), centerTitle: true, backgroundColor: Colors.transparent, foregroundColor: Colors.black, elevation: 0, ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '주문 리스트', style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold), ), Obx(() => Text(controller.order.toString())), Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( '음식', style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold), ), ), Expanded( child: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3), itemCount: controller.foodMenu.length, itemBuilder: ((context, index) { return GestureDetector( onTap: () => controller .addOrder(controller.foodMenu[index].name), //주문리스트에 메뉴이름을 추가하는 함수 child: MenuCard( //card위젯을 따로 만들어서 코딩이 이뻐보이게 만듦 menu: controller.foodMenu[index], //메뉴리스트 순서대로 )); }))) ], ), floatingActionButton: FloatingActionButton.extended( onPressed: controller.clearOrder, //주문리스트 초기화하는 함수 label: const Text('초기화하기'), ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat); } }
lib/view/page/admin_page.dart
// ignore_for_file: prefer_const_literals_to_create_immutables import 'package:flutter/material.dart'; class AdminPage extends StatelessWidget { const AdminPage({super.key}); static const String route = '/admin'; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: const Text('Admin Page'), leading: GestureDetector( onTap: () { Navigator.pop(context); }, child: const Icon(Icons.arrow_back_ios_new)), ), body: SafeArea( child: Column( children: [ const Padding( padding: EdgeInsets.all(16), child: Text('메뉴 추가'), ), const Padding( padding: EdgeInsets.all(16), child: Text('메뉴 삭제'), ), const Padding( padding: EdgeInsets.all(16), child: Text('메뉴 수정'), ), ], )), ); } }
Android Emulator - Pixel_4_XL_API_27_29-ing__5554 2023-03-19 19-31-40.mp412.29MB - 리팩토링이란, 소프트웨어를 보다 쉽게 이해할 수 있도록 만드는 작업이다.