Design Mode note 07-adapter mode and appearance Mode

Source: Internet
Author: User

Design Mode note 07-adapter mode and appearance Mode
1 Introduction
In this chapter, we will carry out a task, to the extent that it is impossible to put a square into a circular hole. That sounds impossible? With the design model, it is possible. Do you still remember the decorator mode? We pack the objects and give them new responsibilities. Now, some objects are packaged for different purposes: to make their interfaces look different from what they are. Why? In this way, you can convert the class interface into the desired interface in the design to implement different interfaces. In addition, we also need to explore another mode to wrap objects to simplify their interfaces.
2 Text
2.1 adapters around us
For example, some AC adapters, change the shape of the socket to match your plug, directly spread the electricity. So what is the object-oriented adapter? In fact, the OO adapter and the real-world adapter play the same role: convert one interface to another to meet the customer's expectations.
2.2 Turkey Converter
Let's take a look at the adapter in use. Remember the duck in Chapter 1? Let's take a look at a slightly simplified version of duck interfaces and classes:

public interface Duck {public void quack();public void fly();}

A green duck is a child of a duck.
Public class MallardDuck implements Duck {// very simple implementation: Just print out what the Duck is doing public void quack () {System. out. println ("Quack");} public void fly () {System. out. println ("I'm flying ");}}

Introduce you to the latest "street play birds": Turkey
Public interface Turkey {// The Turkey will not scream. It will only be called public void gobble (); // The Turkey will fly, although it is not far from public void fly ();}

The following is a specific implementation of Turkey.
Public class WildTurkey implements Turkey {// Brief description of the Turkey action printed public void gobble () {System. out. println ("Gobble gobble");} public void fly () {System. out. println ("I'm flying a short distance ");}}

Now, assume that you are missing a duck object and want to pretend to be a turkey object. Obviously, because the interface for Turkey is different, we cannot use it openly. Write an adapter.
Public class TurkeyAdapter implements Duck {// first, you need to implement the converted type interface, that is, the interface your customer expects to see // then, you need to obtain the object reference to be adapted, here we use the constructor to obtain the reference Turkey turkey; public TurkeyAdapter (Turkey turkey) {this. turkey = turkey;} // now we need to implement the method in the interface. // Quack () is easy to convert between classes. You only need to call gobble () to implement public void quack () {turkey. gobble ();}/** although both interfaces have the fly () method, the flight distance of the turkey is very short, not as long as the duck can fly. * In order for the duck flight to match the turkey flight, the fly () method of the Turkey must be called five times in a row. * @ See headfirst. adapter. ducks. duck # fly () */public void fly () {for (int I = 0; I <5; I ++) {turkey. fly ();}}}

Test Adapter
Public class DuckTestDrive {public static void main (String [] args) {/** create a duck and a Turkey * and pack the Turkey into a turkey adapter, make it look like a duck */MallardDuck Duck = new MallardDuck (); WildTurkey turkey = new WildTurkey (); duck turkeyAdapter = new TurkeyAdapter (turkey ); // test the turkey System. out. println ("The Turkey says... "); turkey. gobble (); turkey. fly (); // test the duck System. out. println ("\ nThe Duck says... "); testDuck (duck); // an important test is coming: Let's try to pass in a turkey System that pretends to be a duck. out. println ("\ nThe TurkeyAdapter says... "); testDuck (turkeyAdapter);} static void testDuck (Duck duck) {duck. quack (); duck. fly ();}}

Adapter mode resolution: 1. The customer calls the adapter method to send a request to the adapter through the target interface; 2. the adapter uses the adapter interface to convert requests to one or more called interfaces of the adapter. 3. The client interface to the call result, but it is not noticed that the adapter is responsible for conversion.
Q: How much "adaptation" does an adapter need? If I need to implement a large Target Interface, there seems to be a lot of work to do. A: That's true. The work required to implement an adapter is indeed proportional to the size of the target interface. Without an adapter, you must rewrite the client code to call this new interface, which will take a lot of effort to do a lot of investigation and code rewriting work. In contrast, it is better to provide an adapter class that encapsulates all the changes in a class.
2.3 define the adapter Mode
Adapter mode: converts an interface of a class to another interface that the customer expects. The adapter allows classes that are not compatible with the original interface to work together. This adapter mode is filled with good OO design principles: Using Object combinations to wrap the adaptors with modified interfaces. This method also has an additional advantage, that is, any subclass of the adapter can be used together with the adapter. Please note that this mode binds customers and interfaces instead of implementations.
2.4 object and class adapters
Now, although the adapter mode has been defined, we haven't told you anything about it. There are actually two types of adapters: "object" adapter and "class" adapter. This chapter covers object adapters and class adapters.
What is a "class" adapter? Why haven't we told you this kind of adapter? Because you need multiple inheritance to implement it, this is impossible in Java. However, when you use multiple inheritance languages, you may still encounter such a requirement. Object Adapter and class adapter use two different adaptation methods: combination (Implementation Interface) and inheritance.
2.5 real-world adapters
Old World enumerator: If you have already used Java, you may remember the collection type, such as Vector, Stack, and HashTable, which all implement a file named elements (). This method returns an Enumeration. This Enumeration interface can walk through each element in the set one by one without knowing how they are managed in the set.
New World Iterator: When Sun introduced the updated collection class, it began to use the Iterator interface, which is similar to the enumeration interface, you can traverse each element in the set type. However, the iterator also provides the ability to delete elements.
Adapt the enumerator to the iterator:
Public class EnumerationIterator implements Iterator {/** because we adapt enumeration to an Iterator, the adapter needs to implement the Iterator interface, and the adapter must look like an Iterator * we use the combination method, when Enumeration is combined into the adapter, an instance variable is used to record enumeration */Enumeration enumeration; public EnumerationIterator (Enumeration enumeration) {this. enumeration = enumeration;} // The hasNext () method of the iterator is actually delegated to the hasMoreElements () public boolean hasNext () {return enumeration. hasMoreElements ();} // next () Delegate to the nextElements () method public Object next () {return enumeration. nextElement ();} // Unfortunately, we cannot support the remove () method of the iterator, so we must discard it. Our practice is to throw an exception public void remove () {throw new UnsupportedOperationException ();}}

2.6 Facade Pattern)
The appearance not only simplifies the interface, but also decouples the customer from the component subsystem. The appearance and adapter can wrap many classes, but the intent of the appearance is to simplify the interface. The intention of the adapter is to convert the interface into different interfaces.
Build the appearance of a home theater, and the code will not be pasted. The main function of the class is to introduce the sub-system instance into the home theater HomeTheaterFacade.
Simplified Interfaces
Public void watchMovie (String movie) {/** watchMovie () processes each previously manually executed task in sequence. Note that each task is processed by the corresponding component in the * delegate subsystem. */System. out. println ("Get ready to watch a movie... "); popper. on (); popper. pop (); lights. dim (10); screen. down (); projector. on (); projector. wideScreenMode (); amp. on (); amp. setDvd (dvd); amp. setSurroundSound (); amp. setVolume (5); dvd. on (); dvd. play (movie );}

Appearance mode: provides a unified interface to access a group of interfaces in the subsystem. The appearance defines a high-level interface to make the subsystem easier to use. Minimum knowledge principle: only talk to your closest friend. When you are designing a system, you should pay attention to the classes it interacts with, whether it is any object, and how it interacts with these classes. In this principle, we hope that we do not allow too many classes to be coupled together in the design, so that we do not need to modify one part of the system and it will affect other parts. If many classes are mutually dependent, the system will become a fragile system, which requires a lot of maintenance costs and will not be easily understood by others because of its complexity.
How can this problem be avoided? This principle provides some guidelines: For any object, in the method of this object, we should only call methods that fall within the following scope: 1. the object itself 2. The object passed in as a parameter of the method (including the constructor) 3. Any object created or instantiated by this method 4. Any component of the object
It sounds a little harsh, isn't it? What is the harm if the method of the object returned from another call is called? If we do this, it is equivalent to distributing requests to the child of another object (and increasing the number of objects we know directly ). In this case, we need to change the principle to require that the object make a request for us, so that we do not need to know the components of this object.
3. Summary of this Chapter
These two modes have already been used intentionally or unintentionally in our coding process. For example, if xml is converted to json, there will be many object methods in the middle. After the final encapsulation, there will be only one xmlToJson () this is the appearance mode. For example, the http class in the serverlet is used to convert the binary stream into a text stream, so that we can directly obtain the text information. The pioneers concluded that learning the design mode may not write good-looking code, but not necessarily write good-looking code without learning the design mode. The design pattern runs through the entire coding process. Some pattern influences our coding habits, sums up and practices, and makes great efforts to advance on the path to architects.








Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.