10장. 클래스

ssu_hyun·2023년 9월 20일
0

Clean Code

목록 보기
11/12
  • 클래스 이름은 해당 클래스 책임을 기술해야 한다.
  • 단일 책임 원칙(Single Responsibility Principle, SRP)
    • 클래스의 책임, 즉 변경할 이유는 단 하나뿐이어야 한다.
    • 큰 클래스보다 작은 클래스 여럿으로 이루어진 시스템이 더 바람직하다. 작은 클래스는 각자 맡은 책임 즉, 변경할 이유가 하나며, 다른 작은 클래스와 협력해 시스템에 필요한 동작을 수행한다.
  • 응집도에 따라 함수를 작은 클래스 여럿으로 분리하게 되면 프로그램의 체계가 잡히고 구조가 더욱 투명해진다.
  • 새 기능을 수정하거나 기존 기능을 변경할 때 건드릴 코드가 최소인 시스템 구조가 바람직하다. 이상적인 시스템이라면 새 기능을 추가할 때 시스템을 확장할 뿐 기존 코드를 변경하지는 않는다.
// 아래 구조는 파생 클래스를 생성하는 방식으로 새 기능에 개방적인 동시에 다른 클래스를 닫아놓는 방식으로 수정에 폐쇄적이다.
public abstract class Sql()
{
	public void Sql(string table, Column[] columns);
    public abstract string Generate();
}

public class CreateSql : Sql
{
	public void CreateSql(string table, Column[] columns);
    public override string Generate();
}

public class SelectSql : Sql
{
	public void SelectSql(string table, Column[] columns);
    public override string Generate();
}

public class InsertSql : Sql
{
	public void InsertSql(string table, Column[] columns, object[] fields);
    public override string Generate();
    private string valuesList(object[] fields, Column[] columns);
}
  • 낮은 시스템 결합도

    • 유연성과 재사용성 증가
    • 각 시스템 요소가 다른 요소로부터 그리고 변경으로부터 잘 격리되어있어 각 요소를 이해하기 쉬워진다.
    • 자연스레 클래스 설계 원칙 DIP(Dependency Inversion Principle)를 따르게 됨
      • DIP : 클래스가 상세한 구현이 아닌 추상화에 의존해야 한다는 원칙
    • 인터페이스, 추상 클래스를 통해 구현 가능
    // 주식 기호를 받아 현재 주식 가격을 반환한다는 추상적인 개념 표현
    // 이와 같은 추상화로 실제로 주가를 얻어오는 출처나 알아오는 방식 등의 구체적인 사실들을 모두 숨김
    public interface IStockExchange
    {
      Money CurrentPrice(string symbol);
    }
    
    // Portfolio는 IStockExchange 인터페이스에 의존
    public class Portfolio
    {
      private IStockExchange exchange;
    
      public Portfolio(IStockExchange exchange)
      {
          this.exchange = exchange;
      }
      //...
    }
    // Test code
    public class PortfolioTest
    {
    	private FixedStockExchangeStub exchange;
        private Porfolio portfolio;
        
        protected void SetUp() 
        {
          exchange = new FixedStockExchangeStub();
          exchange.fix("MSFT", 100);
          portfolio = new Portfolio(exchange);
        }
        
        // Test Method
        public void GivenFiveMSFTTotalShouldBe500()
       {
         try
         {
           portfolio.add(5, "MSTF");
           Assert.assertEquals(500, portfolio.value());
         }
         catch
         {
           Assert.Fail($"예외 발생: {ex.Message}");
         }
       }
    }
      

0개의 댓글