**静态工厂**
2015-12-26 11:17
211 查看
静态工厂
基本概念:
1) Simple Factory模式属于创建型模式,
2) 简单工厂模式是由一个工厂(注意是一个!)对象决定创建出哪一种产品类的实例(例如你到肯德基说你要鸡腿,要薯条,要饮料还是,,,这时肯德基是一
个工厂,客户端只需要点明自己要什么就行)
3)实现方式的实质:由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
下面来看一个例子:
音乐盒接口IMusicBox:
package SimpleFactory;
public interface IMusicBox {
public void play();
}
两种不同的音乐盒播放方式:ViolinBox(小提琴)和 PianoBox(钢琴):
复制代码
package SimpleFactory;
public class ViolinBox implements IMusicBox {
public void play() {
System.out.println(“拨放小提琴音乐^_^”);
}
}
复制代码
复制代码
package SimpleFactory;
public class PianoBox implements IMusicBox {
}
复制代码
下面是一个工厂MusicBoxFactory(Simple Factory的核心,在工厂中根据客户端指定的参数动态创建不同的对象):
复制代码
package SimpleFactory;
public class MusicBoxFactory {
}
复制代码
下面客户端就可以利用工厂模式:(利用工厂模式,客户端只需要对工厂指定你要创建的对象的名字(参数),工厂就可以根据你指定的参数动态创建不同的对象)
复制代码
package SimpleFactory;
public class MusicBoxDemo {
}
复制代码
结果:
拨放钢琴音乐:)
拨放小提琴音乐^_^
上面例子的关系用下图表示:
分析:
工厂角色:被客户端直接调用,根据客户端指定传入的参数,动态创建客户端需要的对象
抽象产品角色:所有对象的父类(接口)
具体产品角色:即工厂的创建目标,工厂创建的对象就是这些具体类的对象。
可以看出,客户端只面对工厂,不用管产品的具体细节,客户只需向工厂要求你需要什么,其他的事情都交给工厂了。
优点:
通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各
自的职责和权利。(简单地说,你到肯德基去只需要说你要鸡腿还是鸡翅就行了,不需要去管鸡腿和鸡翅是怎么做出来的,工厂为你提供了这样一个界面)
不足:
由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新
的类,则就需要改变工厂类了。
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模
块功能的蔓延,对系统的维护和扩展非常不利;
使用场景
工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
从上面的例子也可以看出来,工厂类往往是用反射机制来产生具体对象的。(因为不同类都继承自同一接口),故其扩展性很有限,产品种类必须是事先就知道的哪几
种,什么时候你想要添加一个不是公共接口下的具体类就不行了。
另外,如果你不用反射机制,也不要公共接口,在工厂中使用其他逻辑(例如判断传入的字符串)来根据用户参数创建对象也行,那样扩展性也是很糟糕的,逻辑和添
加只会越来多。
基本概念:
1) Simple Factory模式属于创建型模式,
2) 简单工厂模式是由一个工厂(注意是一个!)对象决定创建出哪一种产品类的实例(例如你到肯德基说你要鸡腿,要薯条,要饮料还是,,,这时肯德基是一
个工厂,客户端只需要点明自己要什么就行)
3)实现方式的实质:由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
下面来看一个例子:
音乐盒接口IMusicBox:
package SimpleFactory;
public interface IMusicBox {
public void play();
}
两种不同的音乐盒播放方式:ViolinBox(小提琴)和 PianoBox(钢琴):
复制代码
package SimpleFactory;
public class ViolinBox implements IMusicBox {
public void play() {
System.out.println(“拨放小提琴音乐^_^”);
}
}
复制代码
复制代码
package SimpleFactory;
public class PianoBox implements IMusicBox {
public void play() { System.out.println("拨放钢琴音乐:)"); }
}
复制代码
下面是一个工厂MusicBoxFactory(Simple Factory的核心,在工厂中根据客户端指定的参数动态创建不同的对象):
复制代码
package SimpleFactory;
public class MusicBoxFactory {
public static IMusicBox createMusicBox(String name) throws InstantiationException, IllegalAccessException, ClassNotFoundException{ // 这边使用的是Java的Reflection机制来产生实例 // 不过客户端不用管啦 // 以后就算改变了这边的程式,客户端程式是不用更改的 return (IMusicBox) Class.forName(name).newInstance(); }
}
复制代码
下面客户端就可以利用工厂模式:(利用工厂模式,客户端只需要对工厂指定你要创建的对象的名字(参数),工厂就可以根据你指定的参数动态创建不同的对象)
复制代码
package SimpleFactory;
public class MusicBoxDemo {
public static void main(String[] args) throws Exception { // playMusicBox(MusicBoxFactory.createMusicBox("PianoBox")); // playMusicBox(MusicBoxFactory.createMusicBox("ViolinBox")); //利用工厂模式,客户端只需要对工厂指定你要创建的对象的名字(参数),工厂就可以根据你指定的参数动态 //创建不同的对象。当然,这些不同的对象就有不同的表现(在本例中通过play表示) playMusicBox(MusicBoxFactory.createMusicBox("SimpleFactory.PianoBox")); playMusicBox(MusicBoxFactory.createMusicBox("SimpleFactory.ViolinBox")); } public static void playMusicBox(IMusicBox musicBox) { musicBox.play(); }
}
复制代码
结果:
拨放钢琴音乐:)
拨放小提琴音乐^_^
上面例子的关系用下图表示:
分析:
工厂角色:被客户端直接调用,根据客户端指定传入的参数,动态创建客户端需要的对象
抽象产品角色:所有对象的父类(接口)
具体产品角色:即工厂的创建目标,工厂创建的对象就是这些具体类的对象。
可以看出,客户端只面对工厂,不用管产品的具体细节,客户只需向工厂要求你需要什么,其他的事情都交给工厂了。
优点:
通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各
自的职责和权利。(简单地说,你到肯德基去只需要说你要鸡腿还是鸡翅就行了,不需要去管鸡腿和鸡翅是怎么做出来的,工厂为你提供了这样一个界面)
不足:
由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新
的类,则就需要改变工厂类了。
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模
块功能的蔓延,对系统的维护和扩展非常不利;
使用场景
工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
从上面的例子也可以看出来,工厂类往往是用反射机制来产生具体对象的。(因为不同类都继承自同一接口),故其扩展性很有限,产品种类必须是事先就知道的哪几
种,什么时候你想要添加一个不是公共接口下的具体类就不行了。
另外,如果你不用反射机制,也不要公共接口,在工厂中使用其他逻辑(例如判断传入的字符串)来根据用户参数创建对象也行,那样扩展性也是很糟糕的,逻辑和添
加只会越来多。
相关文章推荐
- Hadoop:解析Partition
- HTTP电脑发送短信接口调用示例
- Eclipse中配置ServiceMix的远程调试模式
- Android Fragment完全解析,关于碎片你所需知道的一切
- Linux_自制系统服务启动脚本
- 常见数据库的Jdbc连接字符串
- TK1遇到的坑
- 学生信息管理系统(课程设计)
- thinkPHP下的widget扩展用法实例分析
- 数字图像处理(冈萨雷斯第3版)第二章
- 短信API 短信接口说明文档
- Android学习文档之viewpage学习
- ListView 常用属性
- Android Studio 代码混淆
- tomcat中文请求乱码问题
- 关于Intent的七大属性
- Openlayers中热力图的实现
- Android:自己定义PopupMenu的样式(显示图标/设置RadioButton图标)
- Openlayers中热力图的实现
- qTip2 精致的jQuery提示信息插件