OO와 관련하여 응집력을 보는 한 가지 방법은 클래스의 메소드가 개인 속성을 사용하는 경우입니다. 이 답변 here 에서 gnat 이 지적한 LCOM4 (Lhe of Cohesive Methods)와 같은 메트릭을 사용하면 리팩토링 할 수있는 클래스를 식별 할 수 있습니다. 메소드 나 클래스를보다 응집력있게 리팩토링하려는 이유는 다른 사람이 코드 디자인을 더 쉽게 사용할 수 있기 때문 입니다. 날 믿어; 이러한 문제를 해결하면 대부분의 기술 리드 및 유지 보수 프로그래머가 귀하를 사랑합니다.
Sonar 와 같은 빌드 프로세스에서 도구를 사용 하여 코드 기반의 낮은 응집력을 식별 할 수 있습니다 . "응집성" 이 낮은 방법을 생각할 수있는 몇 가지 매우 일반적인 경우가 있습니다 .
사례 1 : 방법은 클래스와 전혀 관련이 없습니다.
다음 예제를 고려하십시오.
public class Food {
private int _foodValue = 10;
public void Eat() {
_foodValue -= 1;
}
public void Replenish() {
_foodValue += 1;
}
public void Discharge() {
Console.WriteLine("Nnngghhh!");
}
}
방법 중 하나는 Discharge()
클래스의 개인 구성원과 접촉하지 않기 때문에 응집력이 부족합니다. 이 경우 개인 멤버는 하나뿐입니다 _foodValue
. 클래스 내부와 관련이 없다면 실제로 거기에 속합니까? 이 메소드는 예를 들어 이름을 지정할 수있는 다른 클래스로 이동할 수 있습니다 FoodDischarger
.
// Non-cohesive function extracted to another class, which can
// be potentially reused in other contexts
public FoodDischarger {
public void Discharge() {
Console.WriteLine("Nnngghhh!");
}
}
함수는 일류 객체이기 때문에 Javascript 에서이 작업을 수행하면 배출이 무료 기능이 될 수 있습니다.
function Food() {
this._foodValue = 10;
}
Food.prototype.eat = function() {
this._foodValue -= 1;
};
Food.prototype.replenish = function() {
this._foodValue += 1;
};
// This
Food.prototype.discharge = function() {
console.log('Nnngghhh!');
};
// can easily be refactored to:
var discharge = function() {
console.log('Nnngghhh!');
};
// making it easily reusable without creating a class
사례 2 : 유틸리티 클래스
이것은 실제로 응집력을 잃는 일반적인 경우입니다. 모두 가 유틸리티 클래스를 좋아 하지만, 이는 일반적으로 설계 결함을 나타내며 대부분의 경우 유틸리티 클래스와 관련된 높은 종속성 때문에 코드베이스를 유지 관리하기가 더 까다로워집니다. 다음 클래스를 고려하십시오.
public class Food {
public int FoodValue { get; set; }
}
public static class FoodHelper {
public static void EatFood(Food food) {
food.FoodValue -= 1;
}
public static void ReplenishFood(Food food) {
food.FoodValue += 1;
}
}
여기에서 유틸리티 클래스가 클래스의 속성에 액세스해야 함을 알 수 있습니다 Food
. 이 경우 유틸리티 클래스의 메소드는 작업을 수행하기 위해 외부 자원이 필요하기 때문에 응집력이 없습니다. 이 경우 작업하는 클래스에 메소드를 갖는 것이 더 좋지 않습니까 (첫 번째 경우와 유사)?
사례 2b : 유틸리티 클래스의 숨겨진 객체
실현되지 않은 도메인 객체가있는 유틸리티 클래스의 또 다른 경우가 있습니다. 문자열 조작을 프로그래밍 할 때 프로그래머가 가지고있는 첫 번째 반응은 유틸리티 클래스를 작성하는 것입니다. 여기에 몇 가지 일반적인 문자열 표현을 확인하는 것과 같습니다.
public static class StringUtils {
public static bool ValidateZipCode(string zipcode) {
// validation logic
}
public static bool ValidatePhoneNumber(string phoneNumber) {
// validation logic
}
}
여기서 가장 잘 모르는 것은 우편 번호, 전화 번호 또는 기타 문자열 반복이 객체 자체가 될 수 있다는 것입니다.
public class ZipCode {
private string _zipCode;
public bool Validates() {
// validation logic for _zipCode
}
}
public class PhoneNumber {
private string _phoneNumber;
public bool Validates() {
// validation logic for _phoneNumber
}
}
이 코드 를 @codemonkeyism 에 의해 직접 다루지 말아야한다는 개념은 @codemonkeyism 에 의해 자세히 설명되어 있지만 프로그래머가 로직을 유틸리티 클래스에 넣어서 문자열을 사용하는 방식 때문에 응집력과 밀접한 관련이 있습니다.