簡體   English   中英

Java - 概括不同的類,類似的方法(不改變子類?)

[英]Java - Generalize different classes, similar methods (without changing the subclasses?)

不確定這是否可行,但我有一個案例,其中兩個接口具有相同的方法。 這些是給定的接口,所以我不能改變它們。

給定接口

interface SomeGivenService {
    boolean authenticate(String username, String password);
    Object someSpecialMethod(Object param);
}

interface AnotherGivenService {
    boolean authenticate(String username, String password);
    String aGreatMethod();
    String sayHello();
}

為了使用這個服務,我創建了一個類,並在此服務拋出錯誤的情況下進行了一些處理。

class SomeGivenServiceConsumer {

    SomeGivenService a;

    public SomeGivenServiceConsumer(SomeGivenService a) {
        this.a = a;
    }

    public authenticate(MyUserPassBean bean) {
        try {
            a.authenticate(bean.username, bean.password);
        } catch (Exception e) {
            throw new MyException();
        }
        ...
    }
}

class AnotherGivenServiceConsumer {

    AnotherGivenService a;

    public AnotherGivenServiceConsumer(AnotherGivenService a) {
        this.a = a;
    }

    public authenticate(MyUserPassBean bean) {
        try {
            a.authenticate(bean.username, bean.password);
        } catch (Exception e) {
            throw new MyException();
        }
        ...
    }
}

我的消費者可以避免這種代碼重復嗎? 我可能會有很多,並希望避免這些重復的代碼。 我最初想過更改我的使用者以接收實現此身份驗證的接口,但由於我無法更改給定的接口,因此不確定這是否可行。

是否可以擁有“具有方法的通用接口?” 或使用一些設計模式? 有任何想法嗎? 我在嘗試什么:

class AnotherGivenServiceConsumer {

    AnotherGivenService a;
    GivenServiceAuthenticable b;

    public AnotherGivenServiceConsumer(AnotherGivenService a, 
                                       GivenServiceAuthenticable b) {
        this.a = a;
        this.b = b;
    }

    public authenticate(MyUserPassBean bean) throws MyException {
        return b.authenticate(bean.username, bean.password);
    }
}

interface GivenServiceAuthenticable<T> {
    boolean authenticate(T givenService, MyUserPassBean bean);
}

class GivenServiceAuthenticableImpl<T> implements GivenServiceAuthenticable<T> {
    boolean authenticate(T givenService, MyUserPassBean bean) {
        try {
            //this won't compile as it's a generic class..
            t.authenticate(bean.username, bean.password); 
        } catch (Exception e) {
            throw new MyException();
        }
        ...
    }
}

其他問題是如果我無法更改它以實現我的新對象如何實例化此對象?

您可以使用模板模式在基類中實現通用功能,同時將單個變化行委托給子類:

abstract class ConsumerBase {
    public void authenticate(MyUserPassBean bean) {
        try {
            authenticate(bean.username, bean.password);
        } catch (Exception e) {
            throw new MyException();
        }
        //...
    }

    protected abstract boolean authenticate(String username, String password);
}

class SomeGivenServiceConsumer extends ConsumerBase {

    SomeGivenService a;

    public SomeGivenServiceConsumer(SomeGivenService a) {
        this.a = a;
    }

    @Override
    protected boolean authenticate(String username, String password) {
        return a.authenticate(username, password);
    }
}

class AnotherGivenServiceConsumer extends ConsumerBase {

    AnotherGivenService a;

    public AnotherGivenServiceConsumer(AnotherGivenService a) {
        this.a = a;
    }

    @Override
    protected boolean authenticate(String username, String password) {
        return a.authenticate(username, password);
    }
}

你需要做的是使用繼承。 然后處理超類中的錯誤即

    class SomeGivenServiceConsumer {

        SomeGivenService a;
        AnotherGivenService b;

        public SomeGivenServiceConsumer(SomeGivenService a) {
            this.a = a;
            try{
             authenticate(MyUserPassBean);
            }catch (Exception e) {
            System.out.println("Thrown exception has been caught : "+e.getMessage());
            }
        }

        public authenticate(MyUserPassBean bean) throws MyException {
                //your implementation here
        }
    }    
    class AnotherGivenServiceConsumer extends SomeGivenServiceConsumer{

        public AnotherGivenServiceConsumer(AnotherGivenService b) {
            super(someGivenService);//construct superclass
            authenticate(MyUserPassBean);//call subclass authenticate method
        }

        @override
        public authenticate(MyUserPassBean bean) throws MyException {
                super.authenticate(MyUserPassBean);//call superclass method
                //your implementation here

        }
    }

然后你構造子類:

public static void main(String[] args) {
    new AnotherGivenServiceConsumer(AnotherGivenService);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM