@@ -0,0 +1,128 @@
+package store.infrastructure.config;
+
+import store.controller.StoreController;
+import store.repository.inventory.InventoryRepository;
+import store.repository.inventory.InventoryRepositoryImpl;
+import store.repository.order.OrderRepository;
+import store.repository.order.OrderRepositoryImpl;
+import store.repository.product.ProductRepository;
+import store.repository.product.ProductRepositoryImpl;
+import store.repository.promotion.PromotionRepository;
+import store.repository.promotion.PromotionRepositoryImpl;
+import store.service.*;
+import store.validator.OrderValidator;
+import store.view.InputView;
+import store.view.OutputView;
+
+public class AppConfig {
+    private ProductRepository productRepository;
+    private InventoryRepository inventoryRepository;
+    private OrderRepository orderRepository;
+    private PromotionRepository promotionRepository;
+
+    private ProductRepository productRepository() {
+        return new ProductRepositoryImpl();
+    }
+
+    private InventoryRepository inventoryRepository() {
+        return new InventoryRepositoryImpl();
+    }
+
+    private OrderRepository orderRepository() {
+        return new OrderRepositoryImpl();
+    }
+
+    private PromotionRepository promotionRepository() {
+        return new PromotionRepositoryImpl();
+    }
+
+    public ProductRepository getProductRepository() {
+        if (this.productRepository == null) {
+            this.productRepository = productRepository();
+        }
+        return this.productRepository;
+    }
+
+    public InventoryRepository getInventoryRepository() {
+        if (this.inventoryRepository == null) {
+            this.inventoryRepository = inventoryRepository();
+        }
+        return this.inventoryRepository;
+    }
+
+    public OrderRepository getOrderRepository() {
+        if (this.orderRepository == null) {
+            this.orderRepository = orderRepository();
+        }
+        return this.orderRepository;
+    }
+
+    public PromotionRepository getPromotionRepository() {
+        if (this.promotionRepository == null) {
+            this.promotionRepository = promotionRepository();
+        }
+        return this.promotionRepository;
+    }
+
+    public StoreFileInputService getStoreFileInputService() {
+        return new StoreFileInputService(
+                getProductRepository(),
+                getPromotionRepository(),
+                getInventoryRepository()
+        );
+    }
+
+    public ProductService getProductService() {
+        return new ProductService(
+                getOrderRepository(),
+                getProductRepository(),
+                getInventoryRepository()
+        );
+    }
+
+    public PromotionService getPromotionService() {
+        return new PromotionService(
+                getProductRepository(),
+                getInventoryRepository()
+        );
+    }
+
+    public OrderValidator getOrderValidator() {
+        return new OrderValidator(
+                getProductRepository(),
+                getInventoryRepository()
+        );
+    }
+
+    public OrderParser getOrderParser() {
+        return new OrderParser();
+    }
+
+    public ReceiptService getDiscountService() {
+        return new ReceiptService(
+                getOrderRepository(),
+                getProductRepository()
+        );
+    }
+
+    public InputView getInputView() {
+        return new InputView();
+    }
+
+    public OutputView getOutputView() {
+        return new OutputView();
+    }
+
+    public StoreController controller() {
+        return new StoreController(
+                getStoreFileInputService(),
+                getProductService(),
+                getPromotionService(),
+                getOrderValidator(),
+                getOrderParser(),
+                getDiscountService(),
+                getInputView(),
+                getOutputView()
+        );
+    }
+}

리뷰: 아 네 맞습니다! 저도 보통 **상단에 public 메소드**를 배치하고, **호출 순서에 따라서 private 메소드를 하단**에 배치하는데요, `AppConfig` 클래스의 경우에는 목적에 맞게 조금 다르게 배치를 했습니다.

`AppConfig` 클래스는 **현재 요구사항에 맞는 구현체**에 따라서 **의존성을 관리**하는 역할을 합니다. 
- 개인적으로 `의존 관계`보다는 `구현체`가 변경되는 경우가 더 빈번할 것이라고 생각했고, **구현체를 반환하는 메소드를 상단으로** 올리는 것이 더 눈에 띌 것이라고 생각했습니다.
- 그리고 현재 서비스에서는 `어떤 구현체에 의해 동작하는지`를 먼저 보여주는게 더 좋다고 생각해서, 레파지토리 구현체를 반환하는 메소드를 맨 위에 배치시켰던 것 같습니다.