Java design pattern notes --------factory pattern------abstract factory pattern

Abstract factory pattern

basic introduction

1) An interface is defined to create a cluster of related or dependent objects without specifying the specific class.
2) The abstract factory pattern can integrate the simple factory pattern and the factory method pattern .
3) From a design perspective , the abstract factory pattern is an improvement of the simple factory pattern (or called further abstraction).
4) The factory is abstracted into two layers , AbsFactory (abstract factory) and concretely implemented factory subclasses . The programmer can use the corresponding factory subclass according to the type of object created . This turns a single simple factory class into a factory cluster, which is more conducive to code maintenance and expansion.

Class Diagram

The abstract factory model completes the pizza project
using the class diagram of Mr. Han from Shang Silicon Valley
Insert picture description here

The improvement is : Our factory is abstracted into two layers. It used to be orders in different regions, but now it is a factory in different places, but there is only one order class. Different orders are completed by different factory implementation subclasses.

Code

First, our 5 pizzas

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 20:06
 * @Description TODO
 * @pojectname 披萨抽象类    设置为抽象类
 */
public abstract class Pizza {
    
    
    //披萨名字
    protected String name;
    //抽象方法 准备原材料  不同的披萨,原材料是不同的
    //因此做成抽象方法
    public abstract void prepare();
    //其他方法,我们人为流程是差不多的所以就是普通方法
    public void bake(){
    
    
        System.out.println(name+"baking;");
    }

    public void cut(){
    
    
        System.out.println(name+"cutting;");
    }
    public void box(){
    
    
        System.out.println(name+"boxing");
    }

    public void setName(String name) {
    
    
        this.name = name;
    }
}
/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/25 20:47
 * @Description TODO
 * @pojectname 代码
 */
public class HNCheesePizza extends Pizza{
    
    
    @Override
    public void prepare() {
    
    
        setName("河南的奶酪披萨");
        System.out.println("给河南奶酪披萨准备原材料");
    }
}
/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/25 20:49
 * @Description TODO
 * @pojectname 代码
 */
public class HNPepperPizza extends  Pizza {
    
    
    @Override
    public void prepare() {
    
    
        setName("河南的胡椒披萨");
        System.out.println("给河南胡椒披萨准备原材料");
    }
}
/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/25 20:47
 * @Description TODO
 * @pojectname 代码
 */
public class LDCheesePizza extends Pizza{
    
    
    @Override
    public void prepare() {
    
    
        setName("伦敦的奶酪披萨");
        System.out.println("给伦敦奶酪披萨准备原材料");
    }
}
/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/25 20:47
 * @Description TODO
 * @pojectname 代码
 */
public class LDPepperPizza extends Pizza{
    
    
    @Override
    public void prepare() {
    
    
        setName("伦敦的胡椒披萨");
        System.out.println("给伦敦胡椒披萨准备原材料");
    }
}

Then we are watching our changes! ! !

Our factory method model is that the order class is made into an abstract class, which has an abstract method, which is responsible for creating instances of different flavors in different places, right?

Let’s look at our simple factory model . It defines a SimpleFactory simple factory to let him create objects.

Then look at our abstract factory pattern

First , he defines a factory interface AbsFactory

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/26 12:18
 * @Description TODO
 * @pojectname 抽象工厂模式的抽象层(接口)
 */
public interface AbsFactory {
    
    
    //让下面的工厂子类具体实现创建什么种类的实例对象
    public Pizza createPizza(String orderType);
}

That there are a method , it is used to create different tastes of different pizza places , that our factory is simple to achieve their own class, factory method is to create a subclass, and now he is the interface, the Who created it?

That is the factory sub-categories responsible for different tastes in different places: HNFactory and LDFactory

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/26 12:20
 * @Description TODO
 * @pojectname 河南工厂子类
 */
public class HNFactory implements AbsFactory {
    
    

    @Override
    public Pizza createPizza(String orderType) {
    
    
        System.out.println("使用的是抽象工厂模式");
        Pizza pizza = null;
        if (orderType.equals("cheese")){
    
    
            pizza = new HNCheesePizza();
        }else if (orderType.equals("pepper")){
    
    
            pizza = new HNPepperPizza();
        }
        return pizza;
    }
}
/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/26 12:20
 * @Description TODO
 * @pojectname 伦敦工厂子类
 */
public class LDFactory implements AbsFactory {
    
    

    @Override
    public Pizza createPizza(String orderType) {
    
    
        System.out.println("使用的是抽象工厂模式");
        Pizza pizza = null;
        if (orderType.equals("cheese")){
    
    
            pizza = new LDCheesePizza();
        }else if (orderType.equals("pepper")){
    
    
            pizza = new LDPepperPizza();
        }
        return pizza;
    }
}

So what does our order category do ? In the previous factory method model, different instance objects were created in the order . Now this work is handed over to the factory subclass. What does the order do?

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/26 12:26
 * @Description TODO
 * @pojectname 订单代码
 */
public class OrderPizza {
    
    
    AbsFactory factory;
    //构造器
    public OrderPizza(AbsFactory factory){
    
    
        setFactory(factory);
    }
    //通过接口依赖
    private void setFactory(AbsFactory factory){
    
    
        Pizza pizza = null;
        String orderType = "";//用户输入种类
        this.factory = factory;
        do {
    
    
            orderType = getType();
//            factory可能是北京的工厂子类,也可能是伦敦的工厂子类
            pizza = factory.createPizza(orderType);
            if (pizza!=null){
    
    
                 pizza.prepare();
                 pizza.bake();
                 pizza.cut();
                 pizza.box();
            }else {
    
    
                System.out.println("订购失败");
                break;
            }
        }while (true);
    }
    //获取客户订购的披萨种类
    private String getType(){
    
    
        try {
    
    
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza 种类:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return "";
        }
    }

}

We found that the constructor of the order class was passed in an interface object , and the interface cannot be new, so it is equivalent to passing an implementation class of the interface object, that is, HNFactory or LDFactory ! That is to say, when the order class is initialized, you have already got the factory of which flavor in that place . In the setFactory method of the order class, pizza gets the flavor type, and you can get the instance objects of your own flavor in different factories! ! !

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/26 12:34
 * @Description TODO
 * @pojectname 代码
 */
public class PizzaStore {
    
    
    public static void main(String[] args) {
    
    

        new OrderPizza(new HNFactory());
    }
}

So far our abstract factory model is complete

Source code analysis and supplement

For example java-util-Calendar class calendar class

import java.util.Calendar;

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/26 12:53
 * @Description TODO
 * @pojectname 工厂模式源码分析
 */
public class test {
    
    
    public static void main(String[] args) {
    
    
        Calendar cal  = Calendar.getInstance();
        System.out.println("年:"+cal.get(Calendar.YEAR));
        System.out.println("月:"+(cal.get(Calendar.MONTH)+1));
        System.out.println("日:"+cal.get(Calendar.DAY_OF_MONTH));
        System.out.println("时:"+cal.get(Calendar.HOUR_OF_DAY));
        System.out.println("分:"+cal.get(Calendar.MINUTE));
        System.out.println("分:"+cal.get(Calendar.SECOND));
    }
}

1. Our Calendar to create an instance when we found through the class name .getInstance to create an instance , that is a static method getInstance Calendar, we went to see the point source

public static Calendar getInstance()
{
    
    
    return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}

Eh! ! ! I found that he called a createCalendar method. Unlike our createPizza method, it passes the time zone and so on. We pass the taste, is it very similar! ! 1

2. Click into the createCalendar method

private static Calendar createCalendar(TimeZone zone,
                                       Locale aLocale)
{
    
    
    CalendarProvider provider =
        LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
                             .getCalendarProvider();
    if (provider != null) {
    
    
        try {
    
    
            return provider.getInstance(zone, aLocale);
        } catch (IllegalArgumentException iae) {
    
    
            // fall back to the default instantiation
        }
    }

    Calendar cal = null;

    if (aLocale.hasExtensions()) {
    
    
        String caltype = aLocale.getUnicodeLocaleType("ca");
        if (caltype != null) {
    
    
            switch (caltype) {
    
    
            case "buddhist":
            cal = new BuddhistCalendar(zone, aLocale);
                break;
            case "japanese":
                cal = new JapaneseImperialCalendar(zone, aLocale);
                break;
            case "gregory":
                cal = new GregorianCalendar(zone, aLocale);
                break;
            }
        }
    }

We only pay attention to the places we are interested in, some places, it doesn’t matter if you don’t understand

Calendar cal = null; ready to create a different instance! ! !

See how he created it **if (aLocale.hasExtensions()) {** to determine what the suffix is

case "buddhis t":
cal = new BuddhistCalendar(zone, aLocale);
break; Is it to create different instance objects based on different suffixes, like our factory method pattern! !

Guess you like

Origin blog.csdn.net/qq_22155255/article/details/111734826