天天看點

【Java設計模式應用】之工廠模式簡單工廠簡單工廠應用工廠方法模式抽象工廠模式應用

小作坊,流水線,代工廠

簡單工廠

由一個工廠對象決定建立哪一種産品類的執行個體,适用于工廠類負責建立的對象較少場景,且用戶端隻需要傳入工廠類的參數,對于如何建立對象不需要關心。
public interface IVideo {
	public void record();
}
           
public class TencentVideo implements IVideo {
	@Override
	public void record() {
		log.info("使用騰訊視訊錄制!");
	}
}
           
public class AlibabaVideo implements IVideo {
	@Override
	public void record() {
		log.info("使用阿裡視訊錄制!");
	}
}
           
public static void main(String[] args) {
	IVideo video_1 = new TencentVideo();
	video_1.record();
	IVideo video_2 = new AlibabaVideo ();
	video_2.record();
}
           
public class VideoFactory {
	public IVideo create(String name) {
		if ("Tencent".equals(name)) {
			return new TencentVideo();
		} else if ("Alibaba".equals(name)) {
			return new AlibabaVideo()
		} else {
			return null;
		}
	}
}
           
public class VideoFactoryTest {
	public static void main(String[] args) {
		VideoFactory factory = new VideoFactory();
		factory.creat("Tencent");
	}
}
           
public class VideoFactory {
	public IVideo create(String name) {
		if (StringUtils.isNotEmpty()) {
			return (IVideo)Class.forName(name).newInstance();
		}
	}
}
           
public static void main(String[] args) {
	VideoFactory videoFactory = new VideoFactory();
	IVideo video = factory.create("com.sfd.spring.TencentVideo");
	video.record();
}
           
public IVideo create(Class<? extends IVideo> clazz) {
	if (null != clazz) {
		return clazz.newInstance();
	}
	return null;
}
           
public static void main(String[] args) {
	VideoFactory videoFactory = new VideoFactory();
	IVideo video = factory.create(TencentVideo.class);
	video.record();
}
           

簡單工廠應用

JDK 源碼

例如 Calendar 類
// java.util.Calendar#createCalendar
private static Calendar createCalendar(TimeZone zone, Locale aLocale) {
	CalendarProvider provider = LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale).getCalendarProvider();
	if (provider != null) {
		return provider.getInstance(zone, aLocale);
	}
	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 (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;
}
           

工廠方法模式

工廠方法模式是指定義一個建立對象的接口,但讓視線這個接口的類來決定執行個體化哪個類,工廠方法模式讓類的執行個體化推遲到子類中進行。
public interface IVideoFactory {
	IVideo create();
}
           
public class TencentVideoFactory implements IVideoFactory {
	public IVideo create() {
		return new TencentVideo();
	}
}
           
public class AlibabaVideoFactory implements IVideoFactory {
	public IVideo create() {
		return new AlibabaVideo();
	}
}
           
public static void main(String[] args) {
	IVideoFactory factory = new AlibabaVideoFactory();
	IVideo video = factory.create();
	video.record();

	factory = new TencentVideoFactory();
	video = factory.create();
	video.record();
}
           

抽象工廠模式

指提供一個建立一系列相關或互相依賴對象的接口,無須指定它們的具體類。用戶端不依賴于産品類執行個體如何被建立、如何被實作細節,強調的是一系列相關的産品對象(屬于同一産品族) 起使用建立對象需要大 重複的代碼需要提供一個産品類的庫,所有的産品以同樣的接口出現,進而使用戶端不依賴于具體實作。
public interface IVideo {
	void record();
}
           
public interface IWord {
	void word();
}
           
public interface IVideoFactory {
	IWord createWord();
	IVideo createVideo();
}
           
public class TencentVideo implements IVideo{
	@Override
	public void record() {
		log.info("使用騰訊視訊錄制!");	
	}
}
           
public class TencentWord implements IWord{
	@Override
	public void word() {
		log.info("使用騰訊話術!");	
	}
}
           
public class TencentFactory implements IVideoFactory {
	public IWord createWord() {
		return TencentWord();
	}
	public IWord createVideo() {
		return TencentVideo();
	}
}
           
public class AlibabaVideo implements IVideo{
	@Override
	public void record() {
		log.info("使用阿裡視訊錄制!");	
	}
}
           
public class AlibabaWord implements IWord{
	@Override
	public void word() {
		log.info("使用阿裡話術!");	
	}
}
           
public class AlibabaFactory implements IVideoFactory {
	public IWord createWord() {
		return AlibabaWord();
	}
	public IWord createVideo() {
		return AlibabaVideo();
	}
}
           
public static void main(String[] args) {
	IVideoFactory factory = new TencentVideoFactory();
	factory.createWord().word();
	factory.createVideo().record();
}
           

應用

public interface IOcrService {
	public Map<String, Map<String,String>> getBankCardInfo(String base64Image);
}
           
public abstract class ConfigedFactory<T> {

	@Autowired
	private SpringContext springContext;

	protected T getBean() {
		String config = PropertiesUtils.get(getConfigKey());
		T bean = (T)springContext.getBean(getConfigMapping().get(config));
		return bean;
	}

	protected abstract String getConfigKey();

	protected abstract Map<String, Class> getConfigMapping();
}
           
public class SpringContext implements ApplicationContextAware {

	private static ApplicationContext appContext = null;
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext){
		appContext = applicationContext;
	}
	public static <T> T getBean(Class<T> clazz) {
		return appContext.getBean(clazz);
	}
}
           
@Service
public class OcrServiceFactory extends ConfigedFactory<IOcrService> implements IOcrService {

	private Map<String, Class> configMapping;

	public static final String CONFIG_KEY = "sfd.ocr.vendor";

	@Override
	protected String getConfigKey() {
		return CONFIG_KEY;
	}

	@Override
	protected Map<String, Class> getConfigMapping() {
		if (configMapping == null) {
			configMapping = new HashMap<String, Class>();
			configMapping.put("YUNMAI", CloudOcrServiceImpl.class);
			configMapping.put("EXOCR", ExOcrServiceImpl.class);
		}
		return configMapping;
	}

	@Override
	public Map<String, Map<String,String>> getBankCardInfo(String base64Image) {
		return getBean().getBankCardInfo(base64Image);
	}
}
           
@Service("EXOCR")
public class ExOcrServiceImpl implements IOcrService {

	@Override
	public Map<String, Map<String,String>> getBankCardInfo(String base64Image) throws BizException {
		Map<String,Map<String,String>> resultMap=new HashMap<>();
		// 通路廠商服務
		// ......
		return resultMap;
	}
}

           
@Service("YUNMAI")
public class CloudOcrServiceImpl implements IOcrService {

	@Override
	public Map<String, Map<String,String>> getBankCardInfo(String base64Image){
		Map<String,Map<String,String>> resultMap=new HashMap<>();
		// 通路廠商服務
		// ......
		return resultMap;
	}
}
           

繼續閱讀