デザインパターン02 - アダプタモード

定義

アダプターデザインパターンは、定義によってアダプタの役割は、別のクラスまたはインタフェースにプロジェクトの要件を満たすために、アダプターを適合させることにより、既存のコードを、要約抽象コードの組織的となっています。換言すれば、クラス・インターフェース・アダプタは、所望の別のインターフェイスクライアント(発信者)に(変換/梱包します)。アダプターデザインパターンは、次の2つの形式があります。

  • クラスアダプタモード(継承されたアダプタ)
  • オブジェクトアダプタモード(デリゲートアダプタを使用)

問題へ

私たちは、1つのアダプタを持って、責任があるためにノートパソコンの付属品を使用し220V、交流電流が変換され12V、ノートパソコン用DC電源、それは役割があるに存在する220V電流が変換され、交流12V直流。それはアダプタがあるので、220VAC電源アダプタを対象とし、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元のユニットを再充電することができると仮定すると、ゲームのアイテムを購入する通貨の場合に102枚の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と継承されたTarget3との間の関係である抽象クラスを、。

アダプタモードキーの役割に

一つのアダプターデザインパターンは、アダプタのデザインパターン分析の役割になりました、より一般的なデザインパターンです。

  • Target(对象)
    该角色负责定义最终的需求,也就是使用适配器模式之后的最终效果。在本次示例中,TargetInterface就是扮演了这个Target角色。

  • Adaptee(被适配)
    该角色定义的是原始的功能,它也许无法直接被利用,但是又不能随意更改,所以它就需要被适配,使得在不修改原始代码的情况下能激活Target的功能。在本次示例中,Rmb扮演了这个角色。

  • Adapter(适配)
    该角色是适配器设计模式的核心角色,他负责适配AdapteeTarget,使得Adaptee来满足Target的需求。在本次示例中,QCoinRechargeableDevice扮演了这个角色。

  • Client(请求者)
    该角色负责调用Target的方法来进行一系列的逻辑处理。在本次示例中,Main类扮演了这个角色。

适配器设计模式UML类图

分析完适配器设计模式的重要角色,当然也得理清适配器设计模式的UML类图。

  • 使用继承的适配器设计模式类图

書き込み絵は、ここで説明しました

  • 使用委托的适配器设计模式类图

書き込み絵は、ここで説明しました

为什么要使用适配器设计模式

我们往往有这种思想,要使用什么类的方法,直接使用不就OK了,或者稍微修改一下已有的代码不就可以使用了吗?其实这种思想是不正确的,因为在现有类的基础下,很多类的方法都经过了严格的测试,贸然地去修改他容易造成意外情况的发生,我们使用适配器设计模式,往往无需修改现有的代码,直接在现有的代码的基础上创建新的代码,这样即使出了错误,我们也能很快从我们新写的代码中找出端倪。使用适配器设计模式,也是对现有代码的一种重复利用。

更多干货分享,欢迎关注我的微信公众号:爪哇论剑(微信号:itlemon)
ここに画像を挿入説明

公開された73元の記事 ウォン称賛84 ビュー470 000 +

おすすめ

転載: blog.csdn.net/Lammonpeter/article/details/82353178