이 복합의 잎 그는 결코 (인터페이스 분리의 위반)를 사용하려고하지 않습니다 추가 제거 및 GetChild 방법이있는 구성 요소를 구현복합 패턴은 솔리드입니까?
때문에 복합 패턴 SOLID의 사용인가? 복합 http://www.dofactory.com/Patterns/PatternComposite.aspx
이 복합의 잎 그는 결코 (인터페이스 분리의 위반)를 사용하려고하지 않습니다 추가 제거 및 GetChild 방법이있는 구성 요소를 구현복합 패턴은 솔리드입니까?
때문에 복합 패턴 SOLID의 사용인가? 복합 http://www.dofactory.com/Patterns/PatternComposite.aspx
당신의 연결 대부분의 책에 도시 된 바와 같이 패턴 진짜 냄새
링크 Component
가 Composite
의 방법을 가지고 있다는 것입니다. 패턴이 상당히 오래되어서 수년간 그런 식으로 반복 되었기 때문일 것으로 생각합니다. 제 생각에는 Composite
에만 합성과 관련된 메소드가 있어야한다는 것입니다.
Composite
이 합성 방법이 있습니다 만, 심지어는이 예에서 (대부분의 고객에게 아이가 있다는 사실을 노출하지 않습니다
public interface Location {
Set<Army> getArmies();
}
public class SingleLocation implements Location {
public Set<Army> getArmies() {
return armies ;
}
private Set<Army> armies = new HashSet<Army>();
}
public class CompositeLocation implements Location {
public Set<Army> getArmies() {
Set<Army> armies = new HashSet<Army>();
for(Location subLocation: subLocations) {
armies.addAll(subLocation.getArmies());
}
return armies;
}
public void addSubLocation(Location location) {
subLocations.add(location);
}
private Set<Location> subLocations = new HashSet<Location>();
}
주, 클라이언트는 원하는 한 위치의 군대 목록 - 많은 하위 위치에 있다는 사실은 부적합합니다.
는 설정에 돌되지 않습니다 정확하게 구현해야하는 일을 마음 디자인 패턴하십시오. 그들을 조리법으로 생각하십시오. 요리하는 동안 조리법을 따라 가면 확실히 정확하게 따라갈 수 있습니다. 그러나 일부 요리사는 조리법에 자신의 단서를 던질 것입니다. 다른 사람들은 심지어 전문가이기 때문에 심지어 그것을 보지도 않고 조리법의 정신으로 무엇인가를 던질 수 있기 때문에 심지어 그것을 보지 않을 것입니다. 디자인 패턴에서도 마찬가지입니다. 그들은 전성있는 요리법입니다.
당신은 또한 그 고체 원리를 너무 멀리 가져갈 수 있습니다. 로버트 마틴 (Robert Martin)의 기사를 읽었을 때 그는 아무 생각없이 원칙을 적용하면 지나치게 복잡한 코드를 산출 할 것이라고 말합니다. 소프트웨어는 일련의 트레이드 오프 및 밸런싱을 통해 설계되었습니다. 때로는 순수 솔리드를 사용하지 않아도되므로 코드가 덜 복잡해집니다. 코드를 완벽하게 캡슐화하고 융통성있게 분리해야한다면 다음과 같은 새로운 프로그래밍 언어를 발명했을 것입니다 .-)
좋은 이유가 있지만 매우 일반적입니다.하지만 표준 버전에는 이유가 있습니다. 예를 들어, 항목은 간단한 합성 이외에도 기능상의 종속성을 가질 수 있습니다. 예를 들어 단락의 높이는 줄 내의 각 문자의 높이에 따라 각 텍스트 줄의 높이에 따라 달라집니다. 별도의 해시를 사용하면 합성 된 항목은 해당 친척을 찾기 위해 합성을 다시 참조해야합니다. 물론 이것에도 장점이 있습니다. 복합 요소는 단락 높이와 같은 하위 트리 요약에 대한 책임을 질 수 있습니다. – Steve314
귀하의 링크에 설명 된 복합 패턴은 Liskov substitution principle 다섯 SOLID 원칙.
Component
만 Composite
예에 대한 이해를 갖는 방법 Add()
. Leaf
은 Component
에서 상속되므로 다른 Component
처럼 Add()
메서드가 있습니다. 그러나 Leafs
아이를 가지고 있지 않기 때문에 다음과 같은 메소드 호출은 의미있는 결과를 반환 할 수 없습니다 :
myLeaf.Add(someChild);
은 그 호출이 추가 호출자에게 다른 방법으로 null
을 반환하거나 표시하는 MethodNotSupportedException
던질 것을 Leaf
에 아이는 말이되지 않습니다.
따라서 Leaf
은 다른 Component
과 같이 취급 할 수 없으므로 예외가 발생할 수 있습니다.Liskov substition 원리 상태 :
S는 하위 유형이다 Q (x)는 T 형식 다음 Q (Y)의 객체 X에 관한 증명 속성 타입 S의 객체 y를위한 진정한해야하자 T.
Components
에는 자녀를 추가 할 수 있다는 속성이 있습니다. 그러나 Leaf
이 Component
의 하위 유형인데도 원칙을 위반하더라도 자녀를 Leaf
에 추가 할 수 없습니다.
유형이 Liskov 대체 원칙 위반으로 간주되기 위해 유형이 상위 유형과의 의미 상 상호 운용성에서 벗어나야하므로 리프 유형이 그렇다면 하위가있는 Add()를 호출하고이어서 호출 할 수 없기 때문입니다 예상되는 인덱스를 가진 GetChild(). 그러나 행위를 단순히 생략하는 것은 위반 행위가 될 수 없습니다. Add() 메서드에는 자식이 추가되었다는 피드백을 제공해야한다는 암시 적 또는 명시 적 계약이 없지만 추가 된 자식을 GetChild() 메서드로 검색 할 수 있다고 가정하는 암시 적 계약이 있습니다. –
BTW, Null Object 패턴이 효과적인 이유는 의미 론적 상호 운용성을 유지하면서 동작을 생략하기 때문입니다. –
Composite를 사용하면 모든 객체를 균일하게 처리 할 수 있으며 코드 냄새의 명확한 표시 인 "instanceOf"를 제거 할 수 있습니다. 언뜻보기에 LSP (Liskov 's)를 존중합니다. 그러나 일반적인 메소드 구현을 차별화하면 LSP를 위반하기 시작할 수 있습니다. 그래서, IMO, 우리는 균형을 유지할 필요가 있습니다.
질문이 명확하지 않습니다. 또한, "솔리드"란 무엇을 의미합니까 – monksy
위의 질문자를위한 솔리드 링크를 추가했습니다. – SingleShot
SRP 및 LSP도 ISP와 함께 위반됩니다. SOLID는 위험합니다. :) – Narek