• 工厂设计模式 抽象工厂


    1.抽象工厂使用场景

    使用端要不断创建某类对象,并且这类对象可以细分为不同种类。此时可以使用抽象工厂,其细分的种类由不同工厂创建。

    2.原则

    1. 使用端依赖抽象
    2. 已经使用的类不再修改,扩展可以添加新的工厂

    3.使用案例

    需求:
    肠粉店有许多功能相同的客户端,需要根据肠粉下单名称,创建肠粉订单对象。
    肠粉可以分为广州口味,北京口味等的肠粉类型。
    根据抽象工厂设计模式类图如下。

    3.1类图

    3.2代码

    abstract class CF {
    	public void prepare();
    	public void cook() {
    		System.out.println("蒸肠粉");
    	}
    	public void oil() {
    		System.out.println("淋上肠粉酱油");	
    	}
    	public void box() {
    		System.out.println("打包发货");
    	}
    }
    
    class BJEggCf extends CF {
    	public void prepare() {
    		System.out.println("准备北京口味的鸡蛋肠粉");
    	}
    }
    class GZEggCF extends CF {
    	public void prepare() {
    		System.out.println("准备广州口味的鸡蛋肠粉");
    	}
    }
    
    interface AbsFactory {
    	public CF createCF(String type);
    }
    
    class BJFactory implements AbsFactory {
    	public CF createCF(String type) {
    		if(type == "egg") {
    			return new BJEggCF();
    		}
    	}
    }
    
    class GZFactory implements AbsFactory {
    	public CF createCF(String type) {
    		if(type == "egg") {
    			return new GZEggCF();
    		}
    	}
    }
    
    //CF对象使用端
    class Client1 {
    	AbsFactory absFactory;
    	public void setFactory(AbsFactory absFactory) {
    		this.absFactory = absFactory;
    	}
    
    	//返回客户下单的类型
    	String getType() {
    		return "egg";
    	}
    
    	public void createOrder() {
    		CF order = this,absFactory.createCF(this.getType);
    	}
    }
    
    class Client2 {
    	AbsFactory absFactory;
    	public void setFactory(AbsFactory absFactory) {
    		this.absFactory = absFactory;
    	}
    
    	//返回客户下单的类型
    	String getType() {
    		return "egg";
    	}
    
    	public void createOrder() {
    		CF order = this,absFactory.createCF(this.getType);
    	}
    }
    

    4.JDK源码分析

    在JDK的Calender类中,就使用了工厂模式创建Calandar对象。

     Calendar a = Calendar.getInstance();
    
    public static Calendar getInstance()
        {
            return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
        }
    
    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;
                    }
                }
            }
            if (cal == null) {
                // If no known calendar type is explicitly specified,
                // perform the traditional way to create a Calendar:
                // create a BuddhistCalendar for th_TH locale,
                // a JapaneseImperialCalendar for ja_JP_JP locale, or
                // a GregorianCalendar for any other locales.
                // NOTE: The language, country and variant strings are interned.
                if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
                    cal = new BuddhistCalendar(zone, aLocale);
                } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                           && aLocale.getCountry() == "JP") {
                    cal = new JapaneseImperialCalendar(zone, aLocale);
                } else {
                    cal = new GregorianCalendar(zone, aLocale);
                }
            }
            return cal;
        }
    
  • 相关阅读:
    若silverlight程序在访问时不加载或白屏怎么办?直接访问xap文件报错:404怎么办?
    iis7 发布mvc3 遇到的HTTP错误 403.14Forbidden Web 服务器被配置为不列出此目录的内容
    Windows server 2008 64bit计划任务运行使用了excel 2003 32bit .net开发组件的程序遇到的问题
    运行WeCompanySite时遇到Error creating context 'spring.root': Error thrown by a dependency of object 'System.Data.SQLite' defined in 'assembly [Spring.Data,
    javascript中创建对象,并序列化为json,通过$.ajax的提交json数据到后台方法,取值为null的问题
    c# web.config 中SessionState的配置(转载)
    第一次使用Excel2007的Microsoft Query遇到的问题及解决:别名的使用
    开博
    谁更了解用户需求
    开发人员为何应该使用 Mac OS X 兼 OS X 小史
  • 原文地址:https://www.cnblogs.com/custoyth/p/13303964.html
Copyright © 2020-2023  润新知