定義
アダプターデザインパターンは、定義によってアダプタの役割は、別のクラスまたはインタフェースにプロジェクトの要件を満たすために、アダプターを適合させることにより、既存のコードを、要約抽象コードの組織的となっています。換言すれば、クラス・インターフェース・アダプタは、所望の別のインターフェイスクライアント(発信者)に(変換/梱包します)。アダプターデザインパターンは、次の2つの形式があります。
- クラスアダプタモード(継承されたアダプタ)
- オブジェクトアダプタモード(デリゲートアダプタを使用)
問題へ
私たちは、1つのアダプタを持って、責任があるためにノートパソコンの付属品を使用し220V
、交流電流が変換され12V
、ノートパソコン用DC電源、それは役割があるに存在する220V
電流が変換され、交流12V
直流。それはアダプタがあるので、220V
AC電源アダプタを対象とし、12V
直流電流は、変換対象とした場合の、発信者のラップトップは、ターゲットオブジェクトです。
JDKのソースコード内のアプリケーションアダプタの設計パターン
必要性から、当然のことながら、アダプターデザインパターンを学んJDK
で、それの痕跡を見つけるために、JDK
ソースコード、場所などの最も一般的のような多くのアダプター・デザイン・パターンの利用IO
転換の流れやコレクションなど。次は一緒にソースコードから我々のアダプターデザインパターンの使い方を分析するためのアップです。
一緒に私たちは読んでjava.io.InputStreamReader(InputStream)
ソースコードの一部を:
InputStreamReader
文字ストリームにバイトストリームの役割は、それらの間の変換は、と言うことです橋(アダプター)、あるInputStreamReader
アダプタで、責任があるInputStream
改宗Reader
あなたが使用できるように、Reader
操作を実行する方法を。
package java.io;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.StreamDecoder;
public class InputStreamReader extends Reader {
private final StreamDecoder sd;
public InputStreamReader(InputStream in) {
super(in);
try {
sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
public String getEncoding() {
return sd.getEncoding();
}
public int read() throws IOException {
return sd.read();
}
public int read(char cbuf[], int offset, int length) throws IOException {
return sd.read(cbuf, offset, length);
}
public boolean ready() throws IOException {
return sd.ready();
}
public void close() throws IOException {
sd.close();
}
}
上記のコードは、「コードの一部を削除した結果である、ソースコード中のコメントだけでなく、いくつかの工法を削除し、ビューのソースポイントから読み込まれ、アダプタのデザインパターンの使用は、このフォーム对象适配器模式
」何であるかについては、「对象适配器模式
我々は意志」、導入における後者の研究では、読者は一時的にあるものを無視することができます对象适配器模式
。」
手動モードアダプタを実現するために設計されています
次に、我々は、アダプタのデザインパターンが稼働している方法を説明するための簡単なコードで、2つのアダプタ設計マニュアルモードを実装します。
元子供が演じてきたQQ
時に再充電する必要があり、ゲームをQ
、コイン使用のQ
ゲームでの購入項目にコインを、このシナリオでは使用して、このシナリオでは、完全に適用アダプタのデザインモードすることができQ
、ゲームのアイテムを買うためにお金を我々のニーズであるが、私たちの目標は(あるTarget
)が、現状は、我々は今、人民元を持っているということです、元はオブジェクト(構成されているAdaptee
)、直接ゲーム内の小道具を購入することはできません人民元は、それがに変換する必要があるQ
通貨が取引することができ、我々ので、また、(アダプタが必要Adapter
に元を変換するための責任がある、)Q
ドル。
上記のテキストによると、私たちはテーブルにまとめることができ、簡単に地理学との関係をクリアすることができます。
役割 | 俳優 | 効果 |
---|---|---|
目標 | ゲームのインターフェイスを購入する小道具 | そこ充電Qコインインタフェースはプリペイドゲームはインターフェイスを小道具Qコインを使用する必要があります |
アダプタ | Q通貨充電器 | 人民元は、Qコイン、完全な再充電に変換されます |
Adaptee | 人民元 | 適合し、オブジェクトが変換され |
上記の関係によると、私たちは、それぞれの役割に対応するクラスまたはインタフェースを作成することでした。ここでは、元のプリペイドの使用をシミュレートQ
使用、通貨をQ
元のユニットを再充電することができると仮定すると、ゲームのアイテムを購入する通貨の場合に10
2枚のQ
コインを、各Q
コインは、ゲームの小道具であることができます。
コード例1:(継承アダプタを使用して)クラスアダプターデザインパターン
- 目標
私たちの目標は、このインタフェースは、ゲームのアイテムを購入することができますが、必要が使用するために、インターフェイスを持つことですQ
購入をするためにお金を。アダプタのデザインパターンでは、それは我々が必要な究極の目標です。
package cn.itlemon.design.pattern.chapter02.adapter.example3;
/**
* @author jiangpingping
* @date 2018/9/6 下午7:43
*/
public interface TargetInterface {
/**
* 购买qCoinCount个游戏道具
*/
void buyGameProps();
}
- Adaptee
今、手持ちの人民元の現状は、あるの必要ので、Q
通貨再帯電装置、同じに人民元の価値Q
通貨。それが直接購入ゲームアイテムに使用することはできませんので、元が必要とされているアダプタのデザインパターンはオブジェクトに適用されるが、それは充電することができます前に、それが合格しなければならないというQ
要件を満たすために、通貨を。
package cn.itlemon.design.pattern.chapter02.adapter.example3;
/**
* 人民币
*
* @author jiangpingping
* @date 2018/9/6 下午7:45
*/
public class Rmb {
private int count;
public Rmb(int count) {
this.count = count;
}
public int getCount() {
return this.count;
}
}
- アダプタ
私たちが必要とするので、Q
通貨再帯電装置、に人民元Q
、その後ドル、とし、ゲームの小道具の機能を購入する必要があります。アダプタのデザインパターンでは、Q
通貨の再充電は、我々はアダプタが必要ということです。
package cn.itlemon.design.pattern.chapter02.adapter.example3;
/**
* Q币充值器
*
* @author jiangpingping
* @date 2018/9/6 下午7:31
*/
public class QCoinRechargeableDevice extends Rmb implements TargetInterface {
private int qCoinCount;
public QCoinRechargeableDevice(int rmbCount) {
super(rmbCount);
this.qCoinCount = getCount() * 10;
}
@Override
public void buyGameProps() {
System.out.println("一共购买了" + qCoinCount + "个道具");
}
}
- メイン
ここで書くためにMain
、次のようにアダプタのデザインパターンの上、当社の設計を検証する方法を、メインのコードは次のようになります。
package cn.itlemon.design.pattern.chapter02.adapter.example3;
/**
* @author jiangpingping
* @date 2018/9/6 下午9:26
*/
public class Main {
public static void main(String[] args) {
TargetInterface qCoinRechargeableDevice = new QCoinRechargeableDevice(10);
qCoinRechargeableDevice.buyGameProps();
}
}
ここでは、私たちがしなければならないQ
通貨充電器充電10
人民元の単位を、あなたは購入完了することができます100
ゲームは変更小道具。もともと人民元で直接購入ゲームアイテムに使用することができない、アダプターのデザインパターンを使用した後、あなたは我々のニーズを完了するために、ゲームのアイテムを購入することができます。
継承されたアダプタUMLのクラス図を使用します
使用して、アダプタがされる機能持って継承Adapter
継承Adaptee
、そして実現しTarget
、これは3の間の関係であることを。
コード例2:(デリゲートアダプタを使用して)オブジェクトアダプタのデザインパターン
ここだけのコードでは、上記に記載されている内に記述された各クラスのために、投稿しました。
- 目標
package cn.itlemon.design.pattern.chapter02.adapter.example4;
/**
* @author jiangpingping
* @date 2018/9/10 下午9:16
*/
public abstract class TargetInterface {
/**
* 购买qCoinCount个游戏道具
*/
public abstract void buyGameProps();
}
- Adaptee
package cn.itlemon.design.pattern.chapter02.adapter.example4;
/**
* 人民币
*
* @author jiangpingping
* @date 2018/9/6 下午7:45
*/
public class Rmb {
private int count;
public Rmb(int count) {
this.count = count;
}
public int getCount() {
return this.count;
}
}
- アダプタ
package cn.itlemon.design.pattern.chapter02.adapter.example4;
/**
* @author jiangpingping
* @date 2018/9/10 下午9:18
*/
public class QCoinRechargeableDevice extends TargetInterface {
private Rmb rmb;
public QCoinRechargeableDevice(Rmb rmb) {
this.rmb = rmb;
}
@Override
public void buyGameProps() {
System.out.println("一共购买了" + rmb.getCount() * 10 + "个道具");
}
}
- メイン
package cn.itlemon.design.pattern.chapter02.adapter.example4;
/**
* @author jiangpingping
* @date 2018/9/10 下午9:16
*/
public class Main {
public static void main(String[] args) {
TargetInterface qCoinRechargeableDevice = new QCoinRechargeableDevice(new Rmb(10));
qCoinRechargeableDevice.buyGameProps();
}
}
UMLのクラス図アダプタを使用するデリゲート(オブジェクト)
使用して、アダプタがされる機能持ち委託Adapter
所有Adaptee
と継承されたTarget
3との間の関係である抽象クラスを、。
アダプタモードキーの役割に
一つのアダプターデザインパターンは、アダプタのデザインパターン分析の役割になりました、より一般的なデザインパターンです。
-
Target(对象)
该角色负责定义最终的需求,也就是使用适配器模式之后的最终效果。在本次示例中,TargetInterface
就是扮演了这个Target
角色。 -
Adaptee(被适配)
该角色定义的是原始的功能,它也许无法直接被利用,但是又不能随意更改,所以它就需要被适配,使得在不修改原始代码的情况下能激活Target
的功能。在本次示例中,Rmb
扮演了这个角色。 -
Adapter(适配)
该角色是适配器设计模式的核心角色,他负责适配Adaptee
和Target
,使得Adaptee
来满足Target
的需求。在本次示例中,QCoinRechargeableDevice
扮演了这个角色。 -
Client(请求者)
该角色负责调用Target
的方法来进行一系列的逻辑处理。在本次示例中,Main
类扮演了这个角色。
适配器设计模式UML类图
分析完适配器设计模式的重要角色,当然也得理清适配器设计模式的UML
类图。
- 使用继承的适配器设计模式类图
- 使用委托的适配器设计模式类图
为什么要使用适配器设计模式
我们往往有这种思想,要使用什么类的方法,直接使用不就OK
了,或者稍微修改一下已有的代码不就可以使用了吗?其实这种思想是不正确的,因为在现有类的基础下,很多类的方法都经过了严格的测试,贸然地去修改他容易造成意外情况的发生,我们使用适配器设计模式,往往无需修改现有的代码,直接在现有的代码的基础上创建新的代码,这样即使出了错误,我们也能很快从我们新写的代码中找出端倪。使用适配器设计模式,也是对现有代码的一种重复利用。
更多干货分享,欢迎关注我的微信公众号:爪哇论剑(微信号:itlemon)