문제

거의 모든 자바 책 내가 읽고 사용하는 방법에 대한 이야기 인터페이스을 공유하는 방법으로 상태 및 행동 물체 사이에는 경우 최초의"구성"보이지 않았을 공유하는 관계이다.

그러나 내가 볼 때마다 건축 디자인하는 응용 프로그램,그들이 할 첫 번째 일을 시작하는 프로그래밍 인터페이스.이유가 무엇입니까?당신은 어떻게 알고 모든 사이의 관계는 개체 내에서 발생하는 인터페이스?이미 알고 있는 경우 그 관계,다는 추상 클래스를 확장?

도움이 되었습니까?

해결책

프로그래밍 인터페이스를 존중하는 것을 의미한"계약"을 사용하여 만든 것 인터페이스입니다.그래서 만약 당신 IPoweredByMotor 인터페이스 start() 방법,미래를 구현하는 클래스,인터페이스들 MotorizedWheelChair, Automobile, 나 SmoothieMaker, 에서 구현하는 방법들을 통해 그 인터페이스을 추가,유연성 시스템이기 때문에,하나의 조각의 코드를 시작할 수 있는 모터의 많은 다른 종류의 것이기 때문에 모든 그 한 조각의 코드를 알아야 하는 것은 그들이 반응하 start().It doesn't matter 는 방법 그들은 시작,단지 그들은 시작해야 합니다.

다른 팁

좋은 질문입니다.나는 당신을 참조하십시오 조쉬 블로흐에서 효과적 Java, 들(item16)왜아보세요 인터페이스의 사용상 추상 클래스입니다.By the way,if you haven't got 이 책 최선을 다하고 있습니다!요약하면 다음과 같습니다 그가 무엇을 말한다:

  1. 기존하는 클래스에 쉽게 장착할 수 있을 구현하고 새로운 인터페이스를 제공합니다. 당신이해야 할 모든 당신은 인터페이스를 구현하고 필요한 방법이 있습니다.기존하는 클래스가 될 수 없는 개조를 쉽게 확장하는 새로운 추상 클래스입니다.
  2. 인터페이스는 이상적인 정의하기 위한 혼합이 가능합니다. 믹스-인터페이스에서 허용하는 클래스를 선언한 추가,선택적인 행위(예를 들어,비교).할 수 있는 선택적 기능에 혼합하는 기본 기능이 있습니다.추상 클래스를 정의할 수 없을 섞-인--클래스를 확장할 수 없습니다 하나 이상이 부모입니다.
  3. 인터페이스 수를 위한 비계층적 프레임워크. 이 있는 경우가 있는 클래스 기능의 많은 인터페이스를 구현할 수 있습니다.없이 인터페이스를 만들고 부풀리는 클래스 계층 구조의 클래스의 모든 조합에 대해 특성,결과로 조합니다.
  4. 인터페이스를 활성화하는 안전 기능이 향상된 기능이 있습니다. 을 만들 수 있습 랩퍼 클래스를 사용하여 장식 패턴으로,강력하고 유연한 디자인입니다.래퍼 클래스를 구현하고 포함되는 동일한 인터페이스,전달에 몇 가지 기능을 기존의 방법을 추가하는 동안 전문화된 동작을 다른 방법이 있습니다.할 수 없습니다 이렇게 추상적인 방법을 사용해야 합 상속 대신에 더 취약하다.

어떤 장점에 대해의 추상 클래스를 제공하는 기본 구현은?을 제공할 수 있습니다 추상적인 골격 구현 클래스와 함께 각 인터페이스입니다.이 결합의 장점을 모두 인터페이스와 추상 클래스입니다.골격 구현 구현을 제공원 부과하지 않고 심각한 제약 조건는 추상 클래스에 힘을 때 그들은 형식으로 정의입니다.예를 들어, 컬렉션 Framework 정의 형식을 사용하여 인터페이스를 제공하기 골격 구현에 대한 각각의 하나입니다.

프로그래밍 인터페이스를 제공하는 여러 가지 혜택:

  1. 에 필요한 GoF 유형 패턴 등의 방문 패턴

  2. 용에 대한 대체를 구현합니다..예를 들어,여러 데이터 액세스 객체 구현이 존재할 수 있는 단일 인터페이스는 초록 데이터베이스 엔진에서 사용(AccountDaoMySQL 및 AccountDaoOracle 모두 구현하 AccountDao)

  3. 클래스를 구현할 수 있는 여러 인터페이스가 있습니다.Java 허용하지 않는 여러 상속의 콘크리트 클래스입니다.

  4. 초록 구현하세요.인터페이스를 포함할 수 있습 방법을 공개 API,hiding implementation details.주요 혜택으로는 깨끗하게 문서화된 API 를 공개하고 잘 계약이 있습니다.

  5. 많이 사용됩해성 주입 프레임워크 등 http://www.springframework.org/.

  6. Java,인터페이스를 만드는 데 사용할 수 있는 동적 프록시- http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Proxy.html.이 매우 효과적으로 사용할 수 있습으로 프레임워크 등의 봄을 수행하는 측면이 지향 프로그래밍입니다.측면 추가 할 수 있습이 매우 유용한 기능을 직접 추가하지 않고도 클래스 java 코드 그는 클래스입니다.의 예에는 이 기능을 포함한 로깅,감사,성능 모니터링,트랜잭션의 경계,등등. http://static.springframework.org/spring/docs/2.5.x/reference/aop.html.

  7. 모 구현,단위 테스트-할 때 의존한 클래스를 구현이의 인터페이스,모의 클래스를 작성할 수 있도를 구현하는 그 인터페이스가 있습니다.모의 클래스를 사용할 수 있을 촉진하는 단위 테스트입니다.

내가 생각하는 이유 중 하나는 추상 클래스가 크게 되어 버려진에 의해 개발자가 될 수 있는 오해이다.

네 갱 썼다:

프로그램의 인터페이스하지 않는 구현합니다.

이 없었습과 같은 것 java 또는 C#인터페이스입니다.그들은 이야기에 대한 객체 지향적 인터페이스의 개념,모든 클래스가있다.에리히 감마가 그것을 언급에서 이 인터뷰.

나는 생각한 모든 규칙에 따라과 원칙에 기계적으로 생각하지 않고 이르게 읽기 어려운동을 이해하고 유지하는 코드 기초입니다.기억하십시오:가장 간단한 일할 수 있는 가능하게 작동합니다.

이유가 무엇입니까?

무엇 때문에 모든 책을 말한다.다음과 같 GoF 패턴,많은 사람들이 그것으로 보편적으로 좋은지 생각하는지 여부에 대해 정말 오른쪽에 디자인이다.

당신은 어떻게 알고 모든 사이의 관계는 개체 내에서 발생하는 인터페이스?

당신이하지 않는 문제입니다.

는 경우 당신은 이미 알고 그 관계, 다운로 확장을 추상 등?

하는 이유는지 확장을 추상 클래스:

  1. 당신이 근본적으로 구현하고 괜찮은 기본 클래스입니다 너무 어렵습니다.
  2. 을 구울 때 당신의 하나에만 기본 클래스에 대한 다른 무언가이다.

지 않은 경우,적용 가 사용하는 추상 클래스입니다.그것은 당신을 저장 시간을 많이 있습니다.

질문에 당신이 요청하지 않았다:

은 무엇 아래의 양면 인터페이스를 사용하여?

를 변경할 수 없습니다.과는 달리는 추상 클래스,인터페이스가 설정에 돌입니다.일단 하나의 사용에서 확장,그것은 것 코드,기간입니다.

나는 진짜로 중 하나가 필요?

대부분의 시간이 없다.정말 열심히 생각하기를 작성하는 개체는 계층 구조로 구성됩니다.큰 문제에서 같은 언어 자바는 그것이 너무 쉽게 만들이 대규모의 복잡한 물체 계층 구조입니다.

을 고려인 예 LameDuck 상속에서 오리입니다.소리 쉽지 않나요?

그럼,필요할 때까지는 것을 나타내는 오리는 부상하고 지금이 가능합니다.또는 나타내는 레임덕이었을 치유하고 다시 걸을 수있는.Java 지 않을 변경할 수 있는 개체의 유형,그래서를 사용하여 하위 종류를 나타내는 파행 실제로 작동하지 않습니다.

프로그래밍 인터페이스를 존중하는 것을 의미한"계약"에 의해 생성 를 사용하는 인터페이스

이것은 하나의 가장 오해한 것에 대한 인터페이스가 있습니다.

방법은 없을 적용하는 모든 그러한 계약으로 인터페이스가 있습니다.인터페이스,정의에 의하여,지정할 수 없습니다 모든 행동에서 모두.수업은 어디에 행동이 일어난다.

이것이 잘못된 믿음이 너무 광범위한 것으로 간주 될 수 있는 기존의 지혜는 많은 사람들에 의해.그것은,그러나,잘못입니다.

그래서 이 문 OP

거의 모든 Java 책 읽기에 대해 이야기 인터페이스를 사용하는 방법으로 을 공유하는 상태 및 행동이체

은 가능하지 않을 수도 있습니다.인터페이스가 되지 않는 상태이나 행동을 했다.그들이 할 수 있을 정의 속성을 구현하는 클래스를 제공해야 하지만,그만큼 가까운 그들은 얻을 수 있습니다.를 공유할 수 없습니다 행동을 사용하여 인터페이스가 있습니다.

할 수 있는 가정을 할 수 있는 사람들이 인터페이스를 구현을 제공하는 일종의 행동을 묵시적의 이름으로 그것의 방법,그러나 그건 아무것도 같은 동일한 것입니다.그 장소를 제한없이 모든 경우에 그러한 방법이라고(예를 들어 시작하기 전에 호출해야 합 Stop).

이 문의

에 필요한 GoF 유형 패턴 등의 방문 패턴

또한 잘못되었습니다.GoF 책을 사용하여 정확하게 제한 인터페이스로 그들의 기능을 사용되는 언어로서의 시간입니다.없음의 패턴에 필요한 인터페이스가 있지만,일부 사용할 수 있습니다.IMO,관찰자에 패턴이 중 하나에서는 인터페이스를 재생할 수 있습니다 더한 역할(지만 패턴은 일반적으로 구현을 사용하여 이벤트가 요즘).에서 방문자가 본 그것은 거의 항상하는 경우 기본 방문자를 구현하는 클래스에서 기본 행동의 각 유형을 위해 방문하는 노드가 필수 입력기를 사용할 수 있습니다.

개인적으로 생각,질문에 대한 대답은 배입니다:

  1. 인터페이스에 의해 볼 수 있으로 많은 것 은 총알(이러한 일반적으로 사람들이 노동에서"계약"misapprehension,또는 생각 하는 인터페이스 마술 분리하며 그들의 코드)

  2. Java 사람들은 매우 초점을 맞추어 사용에 대한 프레임워크가 많이(바로)을 필요로 클래스를 구현하는 자신의 인터페이스

  3. 인터페이스가 최선의 방법은 몇 가지를하기 전에 제네릭이 및 주석(속성에서는 C#)도입되었습니다.

인터페이스는 매우 유용한 언어 기능,그러나 매우 학대된다.증상에는 다음이 포함됩니다:

  1. 인터페이스 단에 의해 구현되는 하나의 클래스

  2. 클래스를 구현하는 여러 인터페이스가 있습니다.종종으로 선전의 이점 인터페이스,일반적으로 그것이 의미하는 클래스에서 질문을 위반하의 원리의 분리는 문제입니다.

  3. 있는 상속 계층의 인터페이스를(자주에 의해 미러 계층의 클래스).이 상황은 당신을 피하려고 이용하여 인터페이스에서 첫 번째 장소입니다.너무 많은 상속가 나쁜 것은 모두에 대해 클래스와 인터페이스를 제공합니다.

이 모든 것은 코드 냄새,IMO.

그것은 하나의 방법을 촉진 느슨한 커플링.

저렴한 커플링,변경 하나의 모듈이 필요하지 않습니다 변화의 구현은 다른 모듈이 있습니다.

좋은 이 개념은 추상적인 공장 패턴.에서 위키피디아를 들어,GUIFactory 인터페이스를 생산하는 버튼 인터페이스를 제공합니다.콘크리트 공장될 수 있습 WinFactory(생산 WinButton),또는 OSXFactory(생산 OSXButton).상상을 작성하는 경우 GUI 응용 프로그램과 당신이 가야하는 모든의 인스턴스 OldButton 클래스고 변경하기 WinButton.그 다음 해야 할 추가 OSXButton 버전입니다.

제 생각에는,당신이 그래서 종종 있기 때문에 그것은 매우 좋은 사례가 종종에서 적용하는 잘못된 상황입니다.

많은 이점이 있 인터페이스는 상대적인 추상 클래스:

  • 로 전환할 수 있습 구현 w/o 을 다시 구축하는 코드에 따라 인터페이스입니다.이를 위해 유용:프록시 클래스,di AOP,etc.
  • 할 수 있는 별도의 API 를 구현에서 당신의 코드입니다.이것은 좋을 수 있기 때문에 그것은 명백한 때 당신은 코드 변경에 영향을 미칠 것입니다 다른 모듈을 사용합니다.
  • 그것은 개발자의 코드를 작성하는 코드가 쉽게 조롱 API 테스트를 위한 목적입니다.

을 얻을 수 있는 가장 이점에서 인터페이스 처리할 때 모듈의 코드입니다.그러나,쉽게 규칙을 확인하는 모듈을 경계해야합니다.그래서 이 방법은 쉽게 이용할 때 특히,처음 설계 일부를 소프트웨어입니다.

것(가@eed3s9n)는 그것을 촉진 느슨한 연결할 수도 있습니다.또한 없이 인터페이스 유닛 테스트 훨씬 더 어려워할 수 없으므로 모의 업체입니다.

왜 악한 것이다:.이 문서는 꽤 많이 직접 질문에 대한 답변을 물었습니다.나는 생각할 수 있는 거의 없는 경우에 당신은 실제로 추상 클래스와는 상황이 많이 그것은 나쁜 생각이 아니다.이는 것을 의미하지 않는 구현을 사용하여 추상 클래스가 나쁘지만,당신이 알아서 할 것이다 그래서 당신은하지 않는 인터페이스 계약에 따라 유물의 몇 가지 특정 구현(포인트의 경우:스택에서 클래스 Java).

한가지 더:그것은 필요하지 않습니다,또는 좋은 연습하는 인터페이스다.일반적으로 식별해야 합할 때는 인터페이스가 필요할 때와 당신은하지 않습니다.이상적인 세계에서 두 번째 경우 구현해야 마지막 클래스의 대부분의 시간입니다.

거기에 몇 가지 훌륭한 대답을 여기에,하지만 당신을 위한 구체적인 이유로보다 더 단위 테스트입니다.

고려하려는 시험 방법 비즈니스에서 논리를 검색하는 현재 세율에 대한 지역 어디 트랜잭션이 발생.이를 위해,비즈니스 로직 클래스는 얘기를 데이터베이스를 통해 저장소:

interface IRepository<T> { T Get(string key); }

class TaxRateRepository : IRepository<TaxRate> {
    protected internal TaxRateRepository() {}
    public TaxRate Get(string key) {
    // retrieve an TaxRate (obj) from database
    return obj; }
}

내 코드를 사용하여 입력 irepository 를 대신 TaxRateRepository.

저장소가 아닌 공용 생성자를 격려하는 사용자(개발)사용하는 공장을 인스턴스화하는 저장소:

public static class RepositoryFactory {

    public RepositoryFactory() {
        TaxRateRepository = new TaxRateRepository(); }

    public static IRepository TaxRateRepository { get; protected set; }
    public static void SetTaxRateRepository(IRepository rep) {
        TaxRateRepository = rep; }
}

공장 곳에서 TaxRateRepository 클래스가 직접 참조.

그래서 당신은 필요를 지원하는 클래스를 이 예제:

class TaxRate {
    public string Region { get; protected set; }
    decimal Rate { get; protected set; }
}

static class Business {
    static decimal GetRate(string region) { 
        var taxRate = RepositoryFactory.TaxRateRepository.Get(region);
        return taxRate.Rate; }
}

그리고 또 다른 다른 구현 irepository 를-는 모의:

class MockTaxRateRepository : IRepository<TaxRate> {
    public TaxRate ReturnValue { get; set; }
    public bool GetWasCalled { get; protected set; }
    public string KeyParamValue { get; protected set; }
    public TaxRate Get(string key) {
        GetWasCalled = true;
        KeyParamValue = key;
        return ReturnValue; }
}

기 때문에 라이브 코드(비즈니스 클래스)를 사용하여 공장를 얻을 저장소 단위에서 테스트를 꽂아서 MockRepository 에 대한 TaxRateRepository.일단체가 만들어,당신은 수 있는 코드를 반환 값이고 불필요한 데이터베이스.

class MyUnitTestFixture { 
    var rep = new MockTaxRateRepository();

    [FixtureSetup]
    void ConfigureFixture() {
        RepositoryFactory.SetTaxRateRepository(rep); }

    [Test]
    void Test() {
        var region = "NY.NY.Manhattan";
        var rate = 8.5m;
        rep.ReturnValue = new TaxRate { Rate = rate };

        var r = Business.GetRate(region);
        Assert.IsNotNull(r);
        Assert.IsTrue(rep.GetWasCalled);
        Assert.AreEqual(region, rep.KeyParamValue);
        Assert.AreEqual(r.Rate, rate); }
}

당신을 기억을 테스트하려면 비즈니스 논리 방법을 뿐만 아니라,저장소,데이터베이스 연결 문자열,etc....다른 테스트에 대한 각각의 사람들.을 수행하여 그것은 이 방법은,당신은 완전히 분리할 코드를 테스트합니다.

측면 혜택을 실행할 수도 있습 단위 테스트 없이 데이터베이스 연결,그것은 더 빠르고,더 많은 휴대용(고 생각 멀티 개발자 팀에 원격 위치에서).

다른 측면 혜택할 수 있는 테스트를 사용하여 개발(TDD)프로세스를 구현 단계에서의 개발이다.지 엄격하게 사용 TDD 만의 혼합 TDD 과 코딩이다.

어떤 의미에서,나는 당신의 질문으로 귀결을 단순히"사용하는 이유 인터페이스 및 아 추상 클래스?" 기술적으로,당신을 달성할 수 있는 느슨한 연결을 모두--기본 구현은 여전히 노출되지 않을 호출하는 코드 사용할 수 있는 추상적 공장에 패턴을 반환하는 기본 구현(인터페이스 구현에 대추상 클래스를 확장자)의 유연성을 증가시키기 위해 디자인.사실,주장할 수 있는 추상 클래스의 제공을 약간 더 때문에,그들은 당신을 모두 필요로 구현을 충족하기 위해 코드("구현해야 합 start()")와 제공하는 기본 구현은("나는 표준 paint()재정의할 수 있습니다려면")--가진 인터페이스 구현을 제공해야 하는 이상으로 이어질 수 있습니다 시간이 부서지기 쉬운 상속을 통해 문제에 대한 인터페이스 변경.

기본적으로,하지만,저는 인터페이스를 사용하여 이 때문에 주로 자바의 단일 상속합니다.는 경우 내에서 상속되어야 합니다 추상 클래스에 의해 사용되는 코드를 호출하는 것을 의미를 잃게 유연성을 상속에서 다른 무언가에도 불구하는 것이 좋을 수도 있습니다(예:코드에 대한 다시 사용하거나 객체 계층).

이유 중 하나는 인터페이스가 허용한 성장과 확장성.예를 들어,예를 들어,당신은 방법을 사용하는 개체 매개변수로,

public void 음료(커피 someDrink) {

}

지금 사용하고 싶을 정확히 동일한 방법은,하지만 전달 hotTea 개체입니다.만,당신은 할 수 없습니다.당신은 그냥 하드 코딩하는 방법을 사용하여 커피체입니다.어쩌면 그것은 좋은,어쩌면 그의 나쁘다.의 단점은 상기가는것은 엄격하게 잠에서 당신과 함께 한 종류의 개체하는 때 당신을 통과하는 모든 종류의합니다.

인터페이스를 사용하여 말,IHotDrink,

인터페이스 IHotDrink{}

고 rewrting 의 위의 방법을 사용하여 인터페이스 객체

public void 음료(IHotDrink someDrink) {

}

지금 전달할 수 있습니다 모든 객체를 구현하는 IHotDrink 인터페이스입니다.확실히,당신은 쓸 수 있는 정확히 동일한 방법은 정확히 동일한 것 서로 다른 개체 매개변수,그런데 왜?당신은 유지 부풀어 코드입니다.

모든 설계에 대해 전니다.

지 않는 경우에는 모든 관계를 사이에 두 개체를 지정한 후 인터페이스는 다음을 수행 가난한 작업을 정의하는 인터페이스는 상대적으로 쉽게 해결할 수 있습니다.

했다면 다이빙으로 똑바로 코딩 및 절반 방법을 통해 누가 그 많은 열심히 해결할 수 있습니다.

당신이 볼 수있에서 이 perl/python/루비 관점:

  • 전달할 때는 객체를 매개 변수로 사용하는 방법 당신이 통과하지 않는 그것의 종류,당신은 단지 알고 있어야 한다는 응답을 어떤 방법

나는 생각을 고려하 java 인터페이스로 비유하는 것을 설명한다.당신은 당신이 정말로 종류를 전달,당신은 그냥 통과 무언가에 응답하는 방법(특색,는 경우).

나는 생각한 주요 사용하는 이유 인터페이스에서 Java 은 제한을 하나의 유산입니다.많은 경우 이 문제로 이어질 불필요한 합병증 코드를 제공합니다.을 살펴 특성에서 스칼라: http://www.scala-lang.org/node/126 특성은 특별한 종류의 추상 클래스,그러나 클래스를 확장할 수 있다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top