(c) Simple Factory mode

Source: Internet
Author: User

Reprint: http://www.cnblogs.com/zuoxiaolong/p/pattern4.html

In the previous chapter we focused on the agent model, and its implementation principle, I believe if you read the entire blog post, you should be familiar with the proxy mode.

In this chapter we discuss the simple factory model, LZ was careless bombast said not and the network spread the teaching mode to explain the same, so now feel to write a blog post pressure is quite big.

How to introduce a simple factory, LZ really cost a lot of thought, this model itself is not complex, but in fact, the more complex the more difficult the mode of writing features, because it is too simple.

To make it easy for you to see the following example, the LZ first gives a definition of a simple factory pattern that is quoted elsewhere.

Definition: From the type of design pattern, the simple factory model belongs to the creation mode, also called the Static Factory method (Factory) mode, but is not one of the 23 gof design patterns. A simple factory model is a factory object that determines which product class instances are created. Simple Factory mode is the simplest and most practical mode in the factory model family, which can be understood as a special implementation of different factory patterns.

One of the most important words in the definition is that a factory object decides which product class to create , and the LZ below will give an example of a real-world application.

In addition to the simple factory model of the class diagram, this class diagram and the above definition are quoted from the Baidu Encyclopedia.

It can be seen that there are a total of three species, one is the factory class creator, one is the product interface IProduct, one is a specific product, such as product A and product B, in this case, the factory is responsible for the entire creation of the logical judgment of the product, so in order to enable the factory class to know which product we need, We need to pass a parameter to the factory class when creating the product to indicate which product we want to create.

The following LZ translates the above class diagram into simpler Java code, allowing for a clear display of the relationships between the classes in the above class diagram.

The first is the product interface.

Public interface IProduct {public    void method ();

Two specific products.

public class ProductA implements iproduct{public    void Method () {        System.out.println ("Product A Method");}    }
public class PRODUCTB implements iproduct{public    void Method () {        System.out.println ("Product B Method");}    }

Here is the factory class.

public class Creator {    private Creator () {} public        static IProduct createproduct (String productName) {        if ( ProductName = = null) {            return null;        }        if (Productname.equals ("A")) {            return new producta ();        } else if (productname.equals ("B")) {            return new PRODUCTB ();        } else {            return null;}}    }

The final client is called and the result is displayed.

public class Client {public    static void Main (string[] args) {        iproduct product1 = creator.createproduct ("A"); C18/>product1.method ();                IProduct product2 = creator.createproduct ("B");        Product2.method ();    }}


The above is a simple example of converting the entire class diagram into Java code, given the class diagram and code of the standard simple factory pattern above, for beginners to familiarize themselves with the general framework of this design pattern, which is easier to understand when we use practical examples to illustrate.

Below LZ to find a you have basically used or in the future to use an example to illustrate the simple factory model, we go to simulate a simple struts2 function.

LZ will make a simple Web project to do the example, which will ignore a lot of details, the purpose is to highlight our simple factory model.

As we all know, we usually develop Web projects with spring as a platform to integrate various components, such as integrated struts2 to complete the business layer and the performance layer of logic, integration Hibernate or Ibatis to complete the persistence layer logic.

STRUTS2 provides the responsibility for separating the data persistence layer, the business logic layer, and the presentation layer in this process, with the Struts2 that we no longer need the servlet, but can use a common action class as a unit to process the business logic and then give the presentation layer to a particular view to handle, Like Jsp,template and so on.

Let's try to write a very, very simple Web project to see what we've been through when it comes to primitive times, when there are no spring,struts2 and so on.

Because the LZ will omit many of the details of the Web architecture process, so it is best that you have done some of the projects, relatively looking will be more experienced, but LZ believe that since the interest to see design patterns, should have basically had this exercise.

The following LZ lists the classes we need in a simple Web project and adds a simple comment.

Import javax.servlet.http.httpservlet;//Assume this is a small Web project, we usually have these classes//This class in the proxy mode, is our data source connection pool, used to produce database connections. Class datasource{}//We generally have such a base class of data access, which depends on the data source class basedao{}    //There is a series of such DAO to inherit Basedao, This series of DAO classes is the data persistence layer class Userdao extends Basedao{}class Persondao extends Basedao{}class EmployeeDAO extends basedao{}    //We'll also have a series of these servlets that are usually dependent on each DAO class, which is our business layer class Loginservlet extends Httpservlet{}class Loginoutservlet extends Httpservlet{}class Registerservlet extends httpservlet{}    

The above is the general structure of our small Web project, you can see the LZ wrote three Servlets, no specific implementation exactly how, but it is not difficult to guess, three servlet functions are to log in, log off, and register the new user's function. Our servlets are generally inherited from HttpServlet, Since we are configuring the servlet on the Web. XML, the class we write needs to implement the Servlet interface, and the transport protocol we usually use is HTTP, so HttpServlet is our best choice, and it helps us accomplish the basic implementation.

But then we have a lot of restrictions, such as a servlet that we can only take responsibility for a single business logic, because all of our business logic is usually focused on dopost, and we can imagine that as our business grows, the number of our servlets will increase rapidly. Not only will the project's class continue to increase, but the most disgusting thing is that every servlet we add will have to write a servlet configuration in Web. Xml.

But if we let a servlet take care of a variety of business logic, then we need to add many if judgments in the Dopost method to determine the current operation.

For example, if we combine the three servlets above, you will be shown the following code in Dopost.

protected void DoPost (HttpServletRequest req, HttpServletResponse resp) throws Servletexception, IOException {        // We add an action parameter to let the servlet make a different business process        String operation = req.getparameter ("operation");        if (operation.equals ("login")) {            System.out.println ("login");        } else if (operation.equals ("register")) {            System.out.println ("register");        } else if (operation.equals ("Loginout")) {            System.out.println ("Loginout");        } else {            throw new RuntimeException ("Invalid operation");        }    }

This is really a bad code, because every time you add a new operation, you have to modify Dopost this method, and a number of business logic is concentrated in this method, will make the code difficult to maintain and expand, the most easy to think of is the following practices. (Tip: If this code structure appears in your project, be sure to try to get rid of it, you can forget about Java and ElseIf and Swich)

protected void DoPost (HttpServletRequest req, HttpServletResponse resp) throws Servletexception, IOException {        // We add an action parameter to let the servlet make a different business process        String operation = req.getparameter ("operation");        if (operation.equals ("login")) {            login ();        } else if (operation.equals ("register")) {            register ();        } else if (operation.equals ("Loginout")) {            loginout ();        } else {            throw new RuntimeException ("Invalid operation");        }    }        private void Login () {        System.out.println ("login");    }        private void Register () {        System.out.println ("register");    }        private void Loginout () {        System.out.println ("Loginout");    }

This will be better than the first way, a method is too long, is not a good sign, wait until you need to modify this part of the business logic, you will regret your original writing, if this code is not written by hand, then please rest assured in the heart Spit Bad bar, because this is not a qualified programmer should write the program.

Although we have split the individual business logic into methods, this is still a violation of the single principle of this little Lori, because our servlet should only deal with business logic, and should not be responsible for the business logic is not related to the processing method positioning such responsibility, this responsibility should be given to the requesting party, Originally in the three servlet processing login, logoff and registration, in fact, this is the case, as the requester, as long as the request Loginservlet, that the request is to log on, the servlet processing this request does not need to appear on the request to determine the operation of the code.

So we need to find a way to determine the business logic to the requester to deal with, recall the next struts2 approach, we can simply simulate the next struts2 approach. Believe that a lot of students should have used STRUTS2, then you must be familiar with the following configuration.

<filter>        <filter-name>struts2</filter-name>        <filter-class> Org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter</filter-class>    </filter>    <filter-mapping>        <filter-name>struts2</filter-name>        <url-pattern>/*</ Url-pattern>    </filter-mapping>

This is the core filter of Struts2, whose task is to assign individual requests, based on the URL address of the request, to find the corresponding action to process the request.

Let's simulate a filter that allocates requests, whose task is to generate a response from the user's request to the servlet processing request, which is actually the role of ProductA and PRODUCTB in the above example, that is, the specific product, and the interface they implement is the servlet's abstract product interface.

We use this filter to eliminate the servlet configuration in Web. XML, and to help us speed up the development process, we write the following filter.

Package Com.web.filter;import Java.io.ioexception;import Javax.servlet.filter;import javax.servlet.FilterChain; Import Javax.servlet.filterconfig;import Javax.servlet.servlet;import Javax.servlet.servletexception;import Javax.servlet.servletrequest;import Javax.servlet.servletresponse;import javax.servlet.http.HttpServletRequest; Import com.web.factory.servletfactory;//Filterpublic class Dispatcherfilter implements filter{private Stati used to dispatch the request        C final String url_separator = "/";        private static final String Servlet_prefix = "servlet/";        Private String Servletname; public void init (Filterconfig filterconfig) throws servletexception {} public void Destroy () {} public void DoFilter (ServletRequest servletrequest, Servletresponse servletresponse,filterchain filterchain) throws IOException,        servletexception {Parserequesturi (httpservletrequest) servletrequest);          To reflect our focus in this section, we use a factory to help us create action if (servletname! = null) {  The simple factory model is used here to create a servlet, and we then forward the request to the servlet to handle the servlet servlet = Servletfactory.createservlet (servletname);        Servlet.service (ServletRequest, servletresponse);        }else {filterchain.dofilter (ServletRequest, servletresponse); }}//is responsible for parsing the request URI, we agreed that the format of the request must be/contextpath/servlet/servletname//Do not doubt the benefits of the contract, because LZ has always believed in a word, the Convention is better than configuring private void Parserequesturi (HttpServletRequest httpservletrequest) {String Validuri = Httpservletrequest.getrequesturi (). Replac        Efirst (Httpservletrequest.getcontextpath () + Url_separator, "");        if (Validuri.startswith (Servlet_prefix)) {servletname = Validuri.split (Url_separator) [1]; }    }}

This filter needs to add the following configuration in Web. XML, this is not much to introduce, directly affixed to it.

<filter>      <filter-name>dispatcherFilter</filter-name>      <filter-class> com.web.filter.dispatcherfilter</filter-class>  </filter>  <filter-mapping>      < filter-name>dispatcherfilter</filter-name>      <url-pattern>/servlet/*</url-pattern>  </filter-mapping>

LZ added some comments in the filter, because the focus of this chapter is simple Factory mode, so here we highlight the protagonist of this chapter, using a simple factory to create a servlet to handle customer requests, of course, if you are a relatively deep Java program Ape, out of curiosity came in a view, May be dismissive of the way this simple factory model is handled, but we can't deviate from the subject, and our goal is not to simulate a struts2, but to introduce a simple factory.

Here's our main character, our servlet factory, which is equivalent to the creator above.

 package com.web.factory;import javax.servlet.servlet;import Com.web.exception.servletexception;import Com.web.servlet.loginservlet;import Com.web.servlet.LoginoutServlet; Import Com.web.servlet.registerservlet;public class Servletfactory {private Servletfactory () {}//a servlet factory dedicated to the production    Each servlet, and the basis for our production is the incoming servletname,//This serlvetname is intercepted by us at filter and passed to the Servlet factory. public static Servlet Createservlet (String servletname) {if (Servletname.equals ("login")) {return new L        Oginservlet ();        }else if (servletname.equals ("register")) {return new Registerservlet ();        }else if (servletname.equals ("Loginout")) {return new Loginoutservlet ();        }else {throw new Servletexception ("Unknown servlet"); }    }}

See here, is not a little feeling, we step by step to eliminate the servlet XML configuration process, in fact, is slowly write a simple Factory mode, but in this, the abstract product interface is ready, that is, the servlet interface.

Although these elseif are not a sign of good code, this simple factory has at least helped us to solve the disgusting XML configuration, which is a great thing to say.

Now we can request/contextpath/servlet/login to access Loginservlet, And no longer need to add the configuration of Web. XML, although in doing so, we are open to the modification, because each additional servlet, we need to modify the factory class, to add an if judgment, but the LZ personally still think I would rather write if, do not want to copy the original let me pain in the XML tag, although I just said let you Forget ElseIf, did I say? All right.. I said, but this is only a temporary way, we can have a lot of ways to eliminate these elseif.

Simple Factory is a relatively simple design mode, it is not even eligible to enter the GOF 23 design patterns, so it can be seen how humble, but it is so humble a design pattern, but also to help us solve the actual problems, although this solution is generally only for small projects.

Writing here, the roles that appear in the simple factory model are already clear. The classes designed in our simple factory are the servlet interface, servletfactory and various specific loginservlet,registerservlet and so on.

summed up is a factory class, a product interface (can actually be an abstract class, even a common parent class, but usually we feel that the interface is the most stable, so basically do not need to consider the ordinary parent case), and a group of products to achieve the interface of the specific products, and this factory class, A concrete implementation class is created based on the parameters passed in, and the transition upward to the interface is returned as a result.

We are here to pull out the simple factory pattern interspersed above, the note has the LZ personal insights to help you understand.

The 
 //is equivalent to the product interface in simple Factory mode interface servlet{}//equivalent to the abstract parent product in simple Factory mode. Note that the simple factory on the network of information for the most simple and easy to understand is only a product interface planning, but this does not mean that there can only be one, the use of design patterns to be flexible. Class HttpServlet implements servlet{}//specific product class Loginservlet extends Httpservlet{}class Registerservlet extends     Httpservlet{}class Loginoutservlet extends httpservlet{}//product Factory public class Servletfactory {private Servletfactory () {}    The typical method of creating a product is generally static, because the factory does not need to have a state. public static Servlet Createservlet (String servletname) {if (Servletname.equals ("login")) {return new L        Oginservlet ();        }else if (servletname.equals ("register")) {return new Registerservlet ();        }else if (servletname.equals ("Loginout")) {return new Loginoutservlet ();        }else {throw new runtimeexception (); }    }}

The above LZ has been the process to pull out, you can compare the standard of the Simple factory code, you will find that they are actually the same design method.

To make the comparison easier for you, LZ here gives the class diagram of the above Java code.

Here is our example of a simple factory pattern class diagram that appears when a servlet is created, and you can compare the first standard class diagram with the same design.

In fact, we still have a lot of optimizations for the logic of creating a servlet instance, but it is limited to what is described in this chapter.

LZ think simple factory This is no technical difficulty, purely in accordance with a number of business scenarios and the design patterns appear, LZ must create a more realistic business scenarios or real examples in order to better interpret. So this time LZ first took out the Web project that we often do, and then LZ will try to cite some examples of practical applications.

OK, the simple factory model of this issue is here, thank you for watching!

Copyright notice

Zuoxiaolong (Zao Jianrong)

Source: Blog Park Zao Jianrong's Technical blog--http://www.cnblogs.com/zuoxiaolong

Your support is the greatest encouragement to bloggers, thank you for your serious reading.

The copyright of this article is owned by the author, welcome to reprint, but without the consent of the author must retain this paragraph, and in the article page obvious location to the original link, otherwise reserves the right to pursue legal responsibility.

(c) Simple Factory mode

Related Article

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.