Adapter mode

intentions

By transforming the interface of one class into another that the customer wants, the Adapter pattern enables classes to work together that would otherwise not work together due to interface incompatibilities

Alias: Wrapper Wrapper

Birth of the adapter pattern

[Product] : Development brother, do you remember our requirements for the first edition?

[development] : What the hell?

[Product] : Did we make a lot of ducks in the first edition? Now we need to make a little Turkey, but the customer is very strange. They want the ducks to have the same ability as turkeys.

[development] : Write duck as Turkey?

[Product] : No, Turkey is Turkey, duck is duck, only special circumstances need to mix together, how to do?

[Development] : Boss, how to do?

【BOSS】 : what Turkey duck, they do not have their own interface, two interface just use the adapter to do, to check their information!


HeadFirst core code

At least we know from the above that you have to have two interfaces to play adapter mode. Let’s just be a question. We’ll talk about it later

The duck interface

/ * ** Duck interface* /
public interface Duck {
    / * ** duck call* /  void quack(a);   / * ** flight* /  void fly(a); } Copy the code

Turkey interface

/ * ** Turkey connector* /
public interface Turkey {
    / * ** the Turkey called* /  void gobble(a);   / * ** flight* /  void fly(a); }  Copy the code

Turkey implementation class

/ * ** Turkey implementation class* /
public class WildTurkey implements Turkey{
    @Override
 public void gobble(a) {  System.out.println("Giggle");  }   @Override  public void fly(a) {  System.out.println("I'm flying, although I'm flying close.");  } } Copy the code

Key point! Adapter!

/ * ** Turkey adapter* Implement the duck interface and hold the Turkey object. Fill the interface with the Turkey object method (and do additional things as well)* /
public class TurkeyAdapter implements Duck{
  Turkey turkey;   @Override  public void quack(a) {  turkey.gobble();  }   @Override  public void fly(a) {  turkey.fly();  }   public TurkeyAdapter(Turkey turkey) {  this.turkey = turkey;  } } Copy the code

The design idea of the adapter pattern is as follows:

  • Target defines a domain-specific interface
  • Client Indicates the object that matches the Target interface
  • Adaptee defines an existing interface that needs to be adapted
  • The Adapter Adapter

Simply put, when we need to mix two unrelated interfaces together, we need to use an adapter to implement interface A, hold object B, and populate the methods of interface A with methods of object B, as well as add some additional logic

It’s like a decorator, right?

In terms of programming language skills, they are very similar, so let’s sort out the similarities and differences:

Similarities:

  • Implementation techniques, are to implement an interface, while holding an object, with the object method to fill the need to implement the method

Difference:

  • Depending on the number of interfaces, decorators typically work with a single interface, while adapters work with a mix of more than two interfaces
  • The purpose of a decorator is to enhance the methods of an object, while an adapter is to make interfaces that would not otherwise work together work together

A wave of interface adapters

Interface adapters are common in Java, such as MouseListener and MouseAdapter

Here’s an example:

/ * ** Define a plethora of methods* /
public interface InterfaceClass {
    void a(a);
 void b(a);  void c(a);  void d(a);  void e(a);  void f(a); } Copy the code

Implement an interface with an abstract class:

public abstract class InterfaceAdapter implements InterfaceClass{

    @Override
    public void a(a) {
        System.out.println("i have override method a");
 }   @Override  public void b(a) {}   @Override  public void c(a) {}   @Override  public void d(a) {}   @Override  public void e(a) {}   @Override  public void f(a) {} } Copy the code

What’s the good of that? For example, MouseAdapter, we must have used it when learning GUI programming, at this point I just want to rewrite the click method, but with the interface directly, there is too much code, need to rewrite a bunch of things, with the interface adapter, it is easy to reduce a lot of useless code, just focus on the method you want to implement

What scenarios apply

  • You want to use an existing class whose interface doesn’t meet your needs
  • You want to create a reusable class that can work with other unrelated classes or classes that may not be compatible

Code/ Practical applications in life

Now mobile phones are pursuing full screen, and a adapter is needed between Android phone and earphone. At this time, the adapter is an adapter, which holds the earphone object and realizes the interface of the phone jack. The headset still provides functions eventually, but it makes contact with objects that could not be connected

UML diagrams


The appearance model

intentions

Providing a consistent interface for a set of interfaces in a subsystem, the Facade pattern defines a high-level interface that makes the subsystem easier to use.

Core idea: provide a common set of external interfaces (high-level APIS) for subsystems

The core code

This pattern is too simple to use so the code is ~

/ * ** Define a top-level interface* /
public interface Computer {

 void open(a); }  public class Cpu implements Computer{  @Override  public void open(a) {  System.out.println("Cpu Open.");  } }  public class Ram implements Computer {  @Override  public void open(a) {  System.out.println("Ram Open.");  } }  public class Ssd implements Computer {  @Override  public void open(a) {  System.out.println("SSD Open.");  } } Copy the code

Appearance of the class

public class FacadeComputer {

    private Cpu cpu;
    private Ram ram;
    private Ssd ssd;
  public FacadeComputer(a) {  this.cpu = new Cpu();  this.ram = new Ram();  this.ssd = new Ssd();  }   /** Cpu On **/  public void onCpu(a) {  this.cpu.open();  }   /** Ram On **/  public void onRam(a) {  this.ram.open();  }   /** Ssd On **/  public void onSsd(a) {  this.ssd.open();  }   /** All On **/  public void allOn(a) {  this.cpu.open();  this.ram.open();  this.ssd.open();  } } Copy the code

Call the contrast

/ * * * ** Recommended reading order: * @see Computer
 * @see Cpu | Ram | Ssd
 * @see FacadeComputer * / public static void main(String[] args) {  // Do not use appearance mode  Computer cpu = new Cpu();  Computer ram = new Ram();  Computer ssd = new Ssd();  cpu.open();  ram.open();  ssd.open();   CodeUtils.spilt();   // Use appearance mode  FacadeComputer facadeComputer = new FacadeComputer();  facadeComputer.allOn(); } Copy the code

What scenarios apply

  • Need to provide a simple interface to a complex subsystem
  • There is a significant dependency between the client and the implementation part of the abstract class (separate the logic, improve subsystem independence and portability)
  • When you need to build a hierarchy of subsystems

Code/ Practical applications in life

The best embodiment of the appearance model in our life is the fund. The essence of the fund is that a professional team collects money to buy stocks. There are many procedures and matters to pay attention to when buying stocks

Related code links

Making the address

  • This is a case study from HeadFirst and GOF
  • Friendly reading instructions are provided