[英]Is this a correct implementation of an adapter pattern?
所以我有兩個類:SoccerPlayer和IceHockeyPlayer
它們都有一些方法自己的接口:ISoccerPlayer和IIceHockeyPlayer
足球運動員:
public class SoccerPlayer implements ISoccerPlayer {
public String[] teammembers;
@Override
public void kickFootball(int meters) {
// Kick the football
}
@Override
public void runForward(double speed) {
// Run forward
}
@Override
public void addTeammembers(String[] memberNames) {
// Add the members
}
}
IceHockeyPlayer:
public class IceHockeyPlayer implements IIceHockeyPlayer {
public ArrayList<String> teammembers;
@Override
public void hitPuck(int meters) {
// Hit the puck
}
@Override
public void skateForward(double speed) {
// Skate forward
}
@Override
public void addTeammembers(ArrayList<String> memberNames) {
// Add the members
}
}
接下來,我創建了一個同時包含SoccerPlayer和IceHockeyPlayer的類,該類同時實現了這兩個接口,這將是我的適配器。
此類中的方法僅調用SoccerPlayer或IceHockeyPlayer的正確方法:
public class Adapter implements ISoccerPlayer, IIceHockeyPlayer {
public SoccerPlayer soccerplayer;
public IceHockeyPlayer icehockeyplayer;
public Adapter(SoccerPlayer soccerplayer, IceHockeyPlayer icehockeyplayer) {
this.soccerplayer = soccerplayer;
this.icehockeyplayer = icehockeyplayer;
}
// SoccerPlayer
@Override
public void kickFootball(int meters) {
this.soccerplayer.kickFootball(meters);
}
@Override
public void runForward(double speed) {
this.soccerplayer.runForward(speed);
}
@Override
public void addTeammembers(String[] memberNames) {
this.soccerplayer.addTeammembers(memberNames);
}
// IceHockeyPlayer
@Override
public void hitPuck(int meters) {
this.icehockeyplayer.hitPuck(meters);
}
@Override
public void skateForward(double speed) {
this.icehockeyplayer.skateForward(speed);
}
@Override
public void addTeammembers(ArrayList<String> memberNames) {
this.icehockeyplayer.addTeammembers(memberNames);
}
}
這是適配器模式的正確實現嗎? 如果沒有,我需要做些什么改變使其成為一體?
那更像是門面。
對於適配器,您會遇到類似
interface SportsPlayer {
public void play(int meters);
public void move(double speed);
}
和類似的適配器
class IceHockeyPlayerAdapter implements SportsPlayer {
private IceHockeyPlayer player;
public IceHockeyPlayerAdapter(IceHockeyPlayer p) { player = p; }
public void play(int meters) {
player.playPuck(meters);
}
public void move(double speed) {
player.skateForward(speed);
}
}
它將“適應”冰球運動員“變成” SportsPlayer
; 因此實際上是另一種方法集。
編輯:
這是真正的JDK的適配器用法。
您知道可以使用try-with-resources來自動關閉資源,並且可以在提交任務后關閉ExecutorService
? 好吧,“嘗試資源”需要一個AutoCloseable
,而ExecutorService
卻沒有實現。 救援工具:
public class AutocloseableExecutorService implements ExecutorService, AutoCloseable {
private ExecutorService delegate;
public AutocloseableExecutorService(ExecutorService d) {
delegate = d;
}
// delegate ExecutorService methods to implement the interface
public void execute(Runnable r) { delegate.execute(r);
// ...
// implement close() for AutoCloseable
public void close() {
delegate.shutdown();
}
}
所以現在您可以像這樣使用它:
public void submitTasks(Runnable... rs) {
try (AutocloseableExecutorService executor = new AutocloseableExecutorService(
Executors.newSingleThreadExecutor())) {
for (Runnable r : rs) executor.submit();
}
}
該方法結束時,該服務將被注冊為關閉。
嚴格來講,這不是適配器。
您可以使用由2個接口組成的對象的組合:
public class Adapter implements ISoccerPlayer, IIceHockeyPlayer
GOF適配器模式通常將一個對象(但可能是多個)適應一個特定的接口 ,以便允許客戶端操縱接口類型,而適配器中使用的適應對象可能不提供該對象所需的方法。客戶端界面。
例如,使用以下客戶端界面:
interface SportPlayer {
void play();
}
假設SoccerPlayer
沒有play()
方法,而是功能上等效的方法,其名稱為playSoccer()
。
為了使SoccerPlayer
對象適應SportPlayer
您可以創建一個SoccerAdapter
:
public class SoccerAdapter implements SportPlayer {
private SoccerPlayer soccerPlayer;
public SoccerAdapter(SoccerPlayer soccerPlayer){
this.soccerPlayer = soccerPlayer;
}
public void play(){
soccerPlayer.playSoccer();
}
}
不,那不是適配器模式。 您使用適配器將呼叫者期望的行為/方法映射到提供者提供的行為。
例:
假設您要構建一個可以處理玩家的機器人。 它只是知道一個播放器看起來像這個界面(我重用您的示例,不管這個有意義與否超出此問題的范圍):
interface Player {
void shoot(int meters);
void move(double speed);
addTeammembers(ArrayList<String> memberNames);
}
該接口的適配器如下所示:
class SoccerPlayerAdapter implements Player {
SoccerPlayer soccerplayer; //set via constructor
void shoot(int meters) {
soccerplayer.kickFootball(meters);
}
void move(double speed){
soccerplayer.runForward(speed);
}
addTeammembers(ArrayList<String> memberNames) {
soccerplayer.addTeammembers(memberNames);
}
}
正如你所看到的SoccerPlayerAdapter
“適應” SoccerPlayer
到Player
,即它映射的方法shoot(int meters)
到kickFootball(int meters)
等。
注意:如果接口不能直接實現,或者由於其他原因這樣做沒有多大意義,那么通常使用適配器。 在您的示例(也是我的示例)中,讓玩家直接實現Player
界面並將kickFootball(meters)
重構為更通用的方法kickFootball(meters)
shoot(meters)
等會更有意義。
適配器模式解決了以下問題:存在現有的Consumer
代碼和現有的Producer
代碼,並且Consumer
代碼的accet類型與Producer
代碼產生的類型不兼容 。
[ Consumer
代碼和Producer
代碼不是標准術語,我更喜歡使用它們來使我的觀點易於理解]
為了解決此問題,我們創建了一個單獨的Adapter
代碼,該代碼使用Producer
代碼中的生產類型並將其轉換為Consumer
代碼使用的類型。
Consumer ---consume (TypeX) //accepts TypeX, Existing code
Producer ----produce () : TypeY //returns TypeY, Existing code
Adapter ---- adapt(TypeY) : TypeX //New code to work with two existing code.accepts TypeY adapts it to TypeX and returns the same.
對於代碼,您可以參考(易於理解) https://www.geeksforgeeks.org/adapter-pattern/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.