Read headFirst design mode and headfirst Design Mode

Source: Internet
Author: User

Read headFirst design mode and headfirst Design Mode

Some of you have solved your problem.

What is the design model? Why should we use design patterns? How to use it? According to the statement in the book and my own understanding, I think this is the case: the problems we encounter are also met by other developers who have used their wisdom and experience to solve the problem, summarize their solutions to the problem so that they can solve other similar problems. The design mode is used to solve problems more conveniently and quickly. Put the pattern into your mind, and then find out where to use it in your design and existing applications. In the past, code reuse was used, and now experience reuse was used.

First, let's repeat the example in the book to simulate the application of a simple duck.

Joe's company decided to develop a duck simulation application. There are various ducks in the system. Ducks can swim and scream. Various ducks have different appearances. This system creates a duck base class, which includes the swim Method for swimming, quack Method for screaming, and display method for displaying the duck appearance. The display method must be rewritten in the subclass of a duck. Like this:

Due to the intensification of competition, the company decided to deal with different things: "Hey, Joe, I think ducks should fly !", "Well, it sounds easy," just add a fly method to Duck. After a few days, the company held a meeting and said, "Joe, how can there be a rubber duck (RubberDuck, no fly, scream) flying in the screen ?", Okay, this is Joe's negligence. Only the real duck can fly. the Rubber Duck can scream, swim, but not fly. Fix it immediately (cover the fly method in RubberDuck and let it do nothing ). But if I need a bait duck (DecoyDuck, neither flying nor calling it), and also rewrite the quack and fly methods in the subclass? Joe also received a notification that the system will be updated from time to time. As for how to update the system, Joe realized that inheritance is not a good method, because every time a duck subclass is added, he is forced to check the quack and fly methods of this subclass and may need to rewrite them. If he directly modifies the methods in the parent class, but some subclasses do not want to modify them, then all the child classes must rewrite these methods.

 

Inherit the code used

Duck

Public abstract class Duck {public void quack () {System. out. println ("");} public void swim () {System. out. println ("swimming") ;}// each duck has a different appearance. Implement public abstract void display () in the subclass; // The method of duck flight public void fly () {System. out. println ("flight ");}}
View Code

MallardDuck

/*** Appearance: green Duck */public class MallardDuck extends Duck {@ Override public void display () {System. out. println ("green Duck ");}}
View Code

RubberDuck

/* ** Rubber Duck * can't scream (quack), but squeak */public class RubberDuck extends Duck {@ Override public void display () {System. out. println ("cute yellow rubber duck");} // the Rubber Duck won't scream (quack), but squeak (squeak) @ Override public void quack () {System. out. println ("");} // The duck cannot fly @ Override public void fly (){}}
View Code

DecoyDuck

/*** Bait Duck, neither flying nor calling */public class DecoyDuck extends Duck {@ Override public void display () {System. out. println ("bait Duck") ;}@ Override public void quack () {System. out. println ("nothing can be done, not called") ;}@ Override public void fly () {System. out. println ("do nothing, do not fly ");}}
View Code

 

What about interfaces?

Extract the action. For example, place the fly method to the Flyable interface. This interface is implemented only by the flying Duck subclass. You can also extract the quack method from the Quackable interface. Like this:

This solves some problems, at least the Rubber Duck will not fly everywhere. But have you ever thought about another problem, that is, the Code cannot be reused, because the methods in the interface can only be abstract, so that the method must be rewritten in each subclass. This is undoubtedly a nightmare jump from one nightmare to another.

 

Change and constant separation

Well, what you believe in software development is -- change. What remains unchanged is change.

Although it is not appropriate to use interfaces, the idea is worth using for reference: Which of the following changes can be used to remove the changing and unchanged elements? The "real" duck can swim, quack and fly, while the Rubber Duck can swim, squeak and squeak. Therefore, it can be a scream, a scream, or a fly that can fly along a straight line or along a curve, so Hefei is changing. Swimming is a random swimming on the water. It can be regarded as a constant. Of course, you have to think that there are many ways to swim, and you can think that it is changing, I think swimming remains unchanged here, so it is necessary to determine the changing and changing conditions based on the actual situation.

 

Software design principles: Change and constant separation

Find out the parts that may change in the application, separate them, and do not mix them with those unchanged. That is, the app may be moved out and encapsulated.

 

Continue Design

Based on the principle of change and constant separation, we can extract and encapsulate the changes. For example, the flight behavior is extracted and designed as an interface FlyBehavior, The called behavior is designed as an interface QuackBehavior, and then the specific behavior is implemented and the method is rewritten, for example:

 

 

Interface Programming

We separate the Duck behavior from the Duck-type Duck. Unlike the past, the previous practice is: the behavior is inherited from the specific implementation in the Duck, or the interface Rewriting Method, both methods depend on implementation, and we are bound to the implementation. In our new design, we separate the behavior, so the behavior is not bound to the Child class of the duck. In other words, the code of the actual behavior is located in the QuackBehavior and FlyBehavior of the specific class, you can dynamically change the behavior at runtime. This is an embodiment of interface Programming. interface Programming refers to super-type programming, not necessarily interface, but abstract class.

 

Software design principles: Interface Programming

Interface Programming, rather than implementation programming

 

Integrated Implementation Code

First, there are two behavior interfaces: QuackBehavior and FlyBehavior.

QuackBehavior

public interface QuackBehavior {    void quack();}
View Code

 

FlyBehavior

/*** Flight behavior interface */public interface FlyBehavior {void fly ();}
View Code

 

QuackBehavior: Quack, Squeak, or MuteQuack

Quack

/*** */Public class Quack implements QuackBehavior {@ Override public void quack () {System. out. println (" ");}}
View Code

 

Squeak

/*** Scream */public class Squeak implements QuackBehavior {@ Override public void quack () {System. out. println (" ");}}
View Code

 

MuteQuack

/*** Do nothing. It will not be called */public class MuteQuack implements QuackBehavior {@ Override public void quack () {System. out. println ("do not do anything, do not call it ");}}
View Code

 

The specific implementation of FlyBehavior: Fly FlyWithWings with wings instead of FlyNoWay

FlyWithWings

/*** Fly with wings */public class FlyWithWings implements FlyBehavior {@ Override public void fly () {System. out. println ("fly with wings ");}}
View Code

 

FlyNoWay

/*** No fly */public class FlyNoWay implements FlyBehavior {@ Override public void fly () {System. out. println ("do nothing, do not fly ");}}
View Code

 

Then, the basic Duck class puts the behavior interface into the Duck as an instance variable. It needs to dynamically change the behavior at runtime, And the setter method can be provided.

Duck

Public abstract class Duck {// private FlyBehavior; private QuackBehavior quackBehavior; // set a default behavior public Duck () {flyBehavior = new FlyWithWings (); quackBehavior = new Quack ();} public void swim () {System. out. println ("swimming");} // each duck has a different appearance. In the subclass, implement public abstract void display (); // execute the cronle method public void into mquack () {quackBehavior. quack () ;}// the method for executing the flight public void unzip mfly () {flyBehavior. fly ();} public void setFlyBehavior (FlyBehavior flyBehavior) {this. flyBehavior = flyBehavior;} public void setQuackBehavior (QuackBehavior quackBehavior) {this. quackBehavior = quackBehavior ;}}
View Code

Note that the abstract class also has constructor methods, but the object cannot be created. The constructor of the abstract class is used to initialize the variable.

 

Two subclasses: MallardDuck and RubberDuck

MallardDuck

/*** The appearance is green Duck */public class MallardDuck extends Duck {@ Override public void display () {System. out. println ("green duck") ;}@ Test public void test1 () throws Exception {MallardDuck mallardDuck = new MallardDuck (); mallardDuck. optional mquack (); mallardDuck. parse mfly (); display ();}}
View Code

 

RubberDuck

/* ** Rubber Duck * can't scream (quack), but squeak */public class RubberDuck extends Duck {@ Override public void display () {System. out. println ("cute yellow rubber Duck");} @ Test public void test1 () throws Exception {Duck rubberDuck = new RubberDuck (); // dynamic behavior change during runtime rubberDuck. setFlyBehavior (new FlyNoWay (); rubberDuck. setQuackBehavior (new Squeak (); rubberDuck. descrimfly (); rubberDuck. optional mquack (); rubberDuck. display ();}}
View Code

 

Encapsulation Behavior

Well, let's take a look at the overall structure: the flight behavior implements the FlyBehavior interface and the QuackBehavior interface. Please note that the way we describe the transaction has also changed, we look at behavior as a group of algorithms. Flight behavior is an algorithm, and behavior is also an algorithm, just like this:

 

We put the variables of the QuackBehavior and FlyBehavior types into the Duck, which actually uses the combination. The system created with the combination is more flexible and won't be inherited. Generally, one change may need to be changed in multiple places.

 

Software Design Principles:

Multi-Purpose Combination and less inheritance

 

Rule Mode

Now, we have finally learned the first pattern: strategy pattern, which introduces the concept of policy pattern.

Defines the algorithm family and encapsulates them separately so that they can replace each other. This pattern makes the algorithm changes independent of the customers who use the algorithm.

 

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.