"재구성-기존 코드 디자인 개선"독서 노트----Change Value to Reference

10278 단어 reference
때때로 당신은 어떤 대상이 전체 국면에서 유일한 것이어야 한다고 생각할 때가 있다. 이것이 바로 인용(Reference)의 개념이다.그것은 당신이 어느 곳에서 그를 수정한 후에 모든 공유 대상이 그를 다시 방문할 때 그에 상응하는 수정을 받아야 한다는 것을 의미한다.값 객체(Value)처럼 수정할 수 없습니다.예를 들어 네가 샤오밍을 알고 나도 샤오밍을 안다. 샤오밍이 갑자기 머리카락을 걷어찼다. 이때 네가 아는 샤오밍과 내가 아는 샤오밍은 모두 같은 사람들이다. 모두 까까머리다. 이 샤오밍이 바로 세계의 유일한 실례이다. 그러나 너는 100위안이 있고 나는 50위안이 있다. 나는 50위안을 20위안밖에 남지 않았다. 네 손에 있는 100위안은 나의 50위안으로 바뀌지 않고 그에 상응하는 수정이 없다.이것이 바로 값 대상이다.C++ 코드에 넣고 인용의 개념에 대해 우리는 참조할 수 있다전편의 예
void setCustomer(const QString &value)

{

    delete m_customer;

    m_customer = NULL;



    m_customer = new Customer(value);

}

나의 m 를 위해'값 대상'이라는 개념을 가지게 되었습니다. 저는 set을 할 때마다 다시 만듭니다. 이렇게 하면 제 대상이 수정할 수 없고 값 대상의 특성을 확보할 수 있습니다.총괄적으로 말하면 인용 대상은'고객','계좌'와 같은 것이고 모든 대상은 실제 세계의 실물을 대표한다.너는 직접'=='으로 두 대상이 같은지 비교할 수 있다. 값 대상은'날짜','돈'과 같은 것이다. 사본의 존재를 걱정할 필요가 없다. 시스템에 100위안에 달하는 수백 수천 개의 대상이 존재할지도 모르지만, 이것은 너와 관계가 없다. 만약 네가 비교하려고 한다면 너도'=='을 다시 불러서 비교할 수 있다.
이것 또한 우리로 하여금 인용 대상과 값 대상 사이에 양난을 일으키게 했다.때때로, 당신은 간단한 값 대상에서 시작하여 수정할 수 없는 소량의 데이터를 저장한 후에, 이 대상에 수정할 수 있는 데이터를 추가하고, 그 어떠한 대상에 대한 수정도 이 대상을 인용하는 모든 지역에 영향을 미치기를 원할 수도 있다.이럴 때는 이 대상을 인용 대상으로 바꾸는 것을 고려해야 한다.
방법:
  • Replace Constructor with Factory Method를 사용합니다.
  • 컴파일, 테스트.
  • 새로운 대상을 방문하는 경로를 어떤 대상이 책임질지 결정한다.정적 사전이나 등록표 대상일 수도 있고, 여러 대상을 새로운 대상의 방문점으로 사용할 수도 있다.
  • 이 인용 대상을 미리 만들어야 하는지, 동적으로 만들어야 하는지를 결정한다.만약 이 인용 대상이 미리 만들어진 것이고, 메모리에서 그들을 읽어내야 한다면, 필요할 때 불러올 수 있도록 확보해야 한다.
  • 공장 함수를 수정하여 인용 대상을 되돌려줍니다.만약 대상이 미리 만들어진 것이라면, 만약 누군가가 존재하지 않는 대상을 요구한다면, 오류를 어떻게 처리해야 할지 고려해야 한다.공장 함수에 Rename Method를 사용해서 이 정보를 전달하기를 원할 수도 있습니다. 이것은 저장된 대상을 되돌려줍니다.
  • 컴파일, 테스트.

  • 예:
    class Customer
    
    {
    
        public:
    
            Customer(const QString &name) :
    
                m_name(name)
    
            {
    
            }
    
    
    
            QString name() const
    
            {
    
                return m_name;
    
            }
    
        private:
    
            const QString m_name;
    
    };
    
    
    
    class Order
    
    {
    
        public:
    
            Order(const QString &customerName) :
    
                m_customer(new Customer(customerName))
    
            {
    
            }
    
    
    
            void setCustomer(const QString &customerName)
    
            {
    
                delete m_customer;
    
                m_customer = NULL;
    
    
    
                m_customer = new Customer(customerName);
    
            }
    
    
    
            QString customerName() const
    
            {
    
                return m_customer->name();
    
            }
    
        private:
    
            Customer *m_customer;
    
    };

    우리는 Replace Data Value with Object의 예를 인용했다. 앞에서 말했듯이 재구성은 이로 인해 끝나지 않았다. 다음은 이 절차를 진행해야 한다.우리는 Customer 클래스가 있는데 그가 Order 클래스에 사용되고 있는 것을 볼 수 있고 대처하는 원칙은'값 대상'이다. 클라이언트 코드는 다음과 같다.
    static int numberOfOrderFor(const QList<Order> &orders, const QString &customerName)
    
    {
    
        int result = 0;
    
    
    
        foreach (Order order, orders)
    
        {
    
            if (order.customerName() == customerName)
    
            {
    
                result++;
    
            }
    
        }
    
    
    
        return result;
    
    }

    현재까지 Customer는 가치 대상에 속하기 때문에 여러 주문이 한 고객에게 속하더라도 이 고객은 모든 Order에게 자신의 것이다.우리는 이러한 현상을 바꾸고 고객 커스터머를 세계에서 유일하게 만들고 싶습니다.즉, 이 주문서들이 같은 Customer 대상을 공유하도록 하는 것은 모든 고객이 하나의 Customer에 대응해야 한다는 것을 의미한다.
    우선 Replace Constructor with Factory Method를 사용하여 Customer 객체의 생성 과정을 제어합니다. 이것은 앞으로도 매우 중요합니다. 다음은 Customer 클래스에서 이 공장 함수를 정의합니다.
    class Customer
    
    {
    
        public:
    
            static Customer *create(const QString &name)
    
            {
    
                return new Customer(name);
    
            }
    
    };

    그리고 원래 구조 함수를 호출했던 곳을 공장 함수로 바꿨다.
    class Order
    
    {
    
        public:
    
            Order(const QString &customerName)
    
            {
    
                m_customer = Customer::create(customerName);
    
            }
    
    };

    그리고 우리는 원래의 Customer의 구조 함수를private라고 성명했다.
    class Customer
    
    {
    
        private:
    
            Customer(const QString &customerName)
    
            {
    
                m_name = name;
    
            }
    
    };

    현재 우리는 이러한 유일한 Customer 대상에 접근하는 방법을 결정해야 한다. 저자는 Order의 한 필드를 통해 접근하는 것을 비교적 좋아하지만, 이 예에는 Customer 대상에 접근할 수 있는 뚜렷한 필드가 없다. 이런 상황에서, 보통 우리는 모든 Customer 대상을 저장하는 등록표 대상을 만들어서 방문점으로 삼아야 한다.우리의 예를 간소화하기 위해서, 우리는 이 등록표를 Customer 클래스의static에 저장하고, Customer를 방문점으로 삼는다.
    static QHash<QString, Customer *> hashTables;

    이 결정을 한 후에 우리는 다음 중요한 결정을 해야 한다. 요청할 때 만들어야 하는지 아니면 미리 만들어야 하는지.여기에서 우리는 후자를 선택했다. 응용 프로그램의 시작 코드에서 우리는 먼저 사용해야 할 커스텀러 대상을 잘 불러왔다. 이 대상들은 데이터베이스에서 왔을 수도 있고 파일에서 왔을 수도 있다.간단하게 보기 위해서, 우리는 코드에서 이러한 대상을 명확하게 생성한다. 어쨌든 이후에 우리는 항상 Subsititute Algorithm를 사용하여 그들의 창설 방식을 바꿀 수 있다.
    class Customer
    
    {
    
        public:
    
        static void loadCustomers()
    
        {
    
            new Customer("Leo")->store();
    
            new Customer("Tom")->store();
    
            new Customer("Marry")->store();
    
        }
    
        private:
    
        void store()
    
        {
    
            hashTables.insert(this.name(), this);
    
        }
    
    };

    미리 만들어진 Customer 객체를 반환하도록 플랜트 함수를 수정해야 합니다.
    static Customer *create(const QString &name)
    
    {
    
        return hashTables.value(name);
    
    }

    create는 항상 기존의 Customer 대상을 되돌려주기 때문에, 이 공장 함수의 이름을 강조하기 위해 Rename Method를 사용해야 합니다.
    class Customer
    
    {
    
        public:
    
            static Customer *getNamed(const QString &name)
    
            {
    
                return hashTables.value(name);
    
            }
    
    };

    좋은 웹페이지 즐겨찾기