Java程序员的日常 —— 注册工厂的妙用
注册工厂是一种很常用的框架书写方法,它适合于快速创建相同类型的对象。
举个栗子
比如一个家具工厂,有沙发、椅子、茶几等等,正常的编程模式是这样的:
//创建
class 沙发{}
class 椅子{}
class 茶几{}
//使用
new 沙发();
new 椅子();
new 椅子();
new 茶几();
如果想要扩展,就需要继续定义class,然后new对象。
但是其实沙发的制作与使用时解耦的,使用者并不需要知道沙发、茶几是怎么制作出来的,只是想使用它而已。
使用注册工厂,相当于沙发、茶几、椅子都统一了一套创建方法,用户只需要去使用就行了。
参考下面的伪码:
//定义创建工厂
interface Factory<T>{
T create();
}
//对象继承这个工厂
class 沙发 extends 家具{
public static class Factory implements a.b.c.Factory<沙发>{
public 沙发 create(){ return new 沙发()}
}
}
class 茶几 extends 家具{
public static class Factory implements a.b.c.Factory<茶几>{
public 茶几 create(){ return new 茶几()}
}
}
class 椅子 extends 家具{
public static class Factory implements a.b.c.Factory<椅子>{
public 椅子 create(){ return new 椅子()}
}
}
//注册到工厂Map中
Map<String,Factory<? extends 家具>> map = new HashMap<>();
map.put("沙发",new 沙发.Factory());
map.put("椅子",new 椅子.Factory());
map.put("茶几",new 茶几.Factory());
//这样在使用的时候,就可以直接用它创建对象了
map.get("沙发").create()
详细代码
Factory.class
package xing.test.thinking.chap14;
public interface Factory<T> {
T create();
}
RegisteredFactories.class
package xing.test.thinking.chap14;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class Part {
public String toString(){
return getClass().getSimpleName();
}
static List<Factory<? extends Part>> partFactories = new ArrayList<Factory<? extends Part>>();//存放所有的对象工厂
//在静态块中添加对象工厂
static{
partFactories.add(new FuelFilter.Factory());
partFactories.add(new AirFilter.Factory());
partFactories.add(new CabinAirFilter.Factory());
partFactories.add(new OilFilter.Factory());
partFactories.add(new FanBelt.Factory());
partFactories.add(new PowerSteeringBelt.Factory());
partFactories.add(new GeneratorBelt.Factory());
}
private static Random rand = new Random(47);
public static Part createRandom(){
int n = rand.nextInt(partFactories.size());
return partFactories.get(n).create();
}
}
class Filter extends Part{}
class FuelFilter extends Filter {
public static class Factory implements xing.test.thinking.chap14.Factory<FuelFilter> {
public FuelFilter create(){
return new FuelFilter();
}
}
}
class AirFilter extends Filter {
public static class Factory implements xing.test.thinking.chap14.Factory<AirFilter> {
public AirFilter create(){
return new AirFilter();
}
}
}
class CabinAirFilter extends Filter {
public static class Factory implements xing.test.thinking.chap14.Factory<CabinAirFilter> {
public CabinAirFilter create(){
return new CabinAirFilter();
}
}
}
class OilFilter extends Filter {
public static class Factory implements xing.test.thinking.chap14.Factory<OilFilter> {
public OilFilter create(){
return new OilFilter();
}
}
}
class Belt extends Part{};
class FanBelt extends Belt {
public static class Factory implements xing.test.thinking.chap14.Factory<FanBelt> {
public FanBelt create(){
return new FanBelt();
}
}
}
class GeneratorBelt extends Belt {
public static class Factory implements xing.test.thinking.chap14.Factory<GeneratorBelt> {
public GeneratorBelt create(){
return new GeneratorBelt();
}
}
}
class PowerSteeringBelt extends Belt {
public static class Factory implements xing.test.thinking.chap14.Factory<PowerSteeringBelt> {
public PowerSteeringBelt create(){
return new PowerSteeringBelt();
}
}
}
public class RegisteredFactories {
public static void main(String[] args) {
for(int i=0 ; i<10 ; i++){
System.out.println(Part.createRandom());
}
}
}
Java程序员的日常 —— 注册工厂的妙用的更多相关文章
- Java程序员的日常——经验贴(纯干货)
工作当中遇到的事情比较杂,因此涉及的知识点也很多.这里暂且记录一下,今天遇到的知识点,纯干货~ 关于文件的解压和压缩 如果你的系统不支持tar -z命令 如果是古老的Unix系统,可能并不认识tar ...
- Java程序员的日常—— 《编程思想》关于类的使用常识
Java虽然利用JVM,让程序员可以放心大胆的使用,可是仍然会出现内存泄露等问题.世上没有绝对的银弹,因此也不能完全把所有的任务都交给JVM,了解Java中的初始化与垃圾回收还是必不可少的知识. 关于 ...
- Java程序员的日常—— Properties文件的读写
在日常的Java程序开发中,Properties文件的读写是很常用的.经常有开发系统通过properties文件来当做配置文件,方便用户对系统参数进行调整. 那么本片就来简单的介绍下,如何使用Prop ...
- Java程序员的日常—— 垃圾回收中引用类型的作用
在Java里面,是不需要太过于关乎垃圾回收,但是这并不意味着开发者可以不了解垃圾回收的机制,况且在java中内存泄露也是家常便饭的事情.因此了解垃圾回收的相关知识就显得很重要了. 引用,在垃圾回收中是 ...
- Java程序员的日常 —— 多进程开发
最近再弄进程管理相关的工作,因此必要的就涉及到各种系统下关于进程的管理. 这里简单的介绍下: 如何在Java中执行命令 在windows下肯定是dos命令了,而在linux则为shell命令.执行的方 ...
- Java程序员的日常——存储过程知识普及
存储过程是保存可以接受或返回用户提供参数的SQL语句集合.在日常的使用中,经常会遇到复杂的业务逻辑和对数据库的操作,使用存储过程可以进行封装.可以在数据库中定义子程序,然后把子程序存储在数据库服务器, ...
- Java程序员的日常 —— 《编程思想》持有对象
集合框架可以说是Java里面必备的知识点了,日常的使用中也会遇到各种情况需要使用到集合.下面就简单介绍下各种集合的使用场景: List List可以看做是数组,实现的方式有两种: ArrayList ...
- Java程序员的日常 —— 工作一天的收获
看题目可能是扯皮,其实还是有很多专业知识的.从最开始没有注意到设计原则,到后面的jquery实战技巧,都是今天一天碰到的问题. 每天整理一点点,每天收获一点点. 关于软件设计 在设计系统结构的时候,一 ...
- Java程序员的日常—— Arrays工具类的使用
这个类在日常的开发中,还是非常常用的.今天就总结一下Arrays工具类的常用方法.最常用的就是asList,sort,toStream,equals,copyOf了.另外可以深入学习下Arrays的排 ...
随机推荐
- Android中的接口回调技术
Android中的接口回调技术有很多应用的场景,最常见的:Activity(人机交互的端口)的UI界面中定义了Button,点击该Button时,执行某个逻辑. 下面参见上述执行的模型,讲述James ...
- SRETAN
SRETAN (sretan.pas/c/cpp) 题目描述 4和7是幸运数字,输入k,输出第k个只含有4和7的数. 输入格式 一行一个数k 输出格式 一行一个数表示答案 样例输入 3 样例输出 44 ...
- 【分块打表】bzoj3798 特殊的质数
块大小为10^5. #include<cstdio> using namespace std; const int table[] = {0, 4784, 8978, 12981, 169 ...
- (转)如何为你的Viewcontroller瘦身
View controllers are often the biggest files in iOS projects, and they often contain way more code t ...
- delphi 读写文本
将字符串写入txt文档,读取txt文档中的内容. //一次写字符串到文本文件,每次都会将原来的内容替换掉. procedure FilePutContents(f,s:String); // f为文件 ...
- usage of elinks (命令行下的firefox)
No.0 Press "Esc" to show main menu ============================================= No.1 tyep ...
- java中类型转换
1.基本数据类型转换 char, byte,short,int,long,float,double,boolean (1)小类型数据可以直接赋给大类型数据 例:char a=' ...
- 初识selenium--百度实例录制
Selenium 是一个web的自动化测试工具,不少学习功能自动化的朋友首选的就是Selenium,它相比QTP有许多优点(QTP笔者由于种种原因暂未使用过O(∩_∩)O哈!): ①Selenium是 ...
- highcharts 柱状图 折线图 混合 双纵轴显示
$(function () { $('#container').highcharts({ chart: { zoomType: 'xy' }, title: { text: '' }, colors: ...
- C++混合编程之idlcpp教程Python篇(8)
上一篇在这 C++混合编程之idlcpp教程Python篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial6中,同样加入了四个文件:Pyt ...