设计模式之工厂模式
2017-11-29 10:54
369 查看
一、设计模式之工厂模式:
工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它和结构型模式,行为型模式是三大主要的设计模式,除了这些之外,还有并发型模式,线程型模式,工厂模式提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象,将创建对象和使用对象分开。
使用说明:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
关键:创建过程在其子类执行。
优点:
1、屏蔽产品的具体实现,调用者只关心产品的接口。
2、将客户和实际创建具体产品的代码分隔开(解耦)
3、个调用者想创建一个对象,只要知道其接口名称就可以了。
4、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
缺点:
每次增加一个产品时,都需要增加一个具体类和修改对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。(使用反射机制可以解决每次增加一个产品时,都需要增加一个对象实现工厂的缺点。)
应用实例:
1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。。
2、Hibernate、mybaits换数据库只需换方言和驱动就可以,不用去管内部是怎么实现转化的。
使用场景:
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
简单的代码示例:
(1)先创建一个产品接口类Shape:
public interface Shape {
void draw();
}
(2)创建产品接口的实现类Circle、Rectangle、Square:
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("调用Circle的draw()方法");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("调用Rectangle的draw()方法");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("调用Square的draw()方法");
}
}
(3)创建一个工厂ShapeFactory ,生成基于给定信息的实体类对象:
public class ShapeFactory {
//使用 getShape方法获取形状类型的对象
public Shape getShape(String shapeType){
if(shapeType==null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
}else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
System.out.println("请输入正确的shapeType类型");
return null;
}
//反射机制:使用反射机制可以解决每次增加一个产品时,都需要增加一个对象实现工厂的缺点
public static Object getClass(Class<? extends Shape> clazz){
Object obj=null;
try{
obj=Class.forName(clazz.getName()).newInstance();
/*
* 1.Class.forName(String className)这个方法传入一个类型的全路径的名字
* (也就是带包的完整名字),会返回一个字节码类型(也就是Class类型)的实例。
* 2.然后再用这个字节码类型的实例clazz调用newInstance()方法
* 会返回一个Object类型的对象。
*/
}catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return obj;
}
}
(4)生产产品:
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory=new ShapeFactory();
//获取Circle的对象,并调用他的draw方法
Shape shape1=shapeFactory.getShape("CIRCLE");
shape1.draw();
Shape shape2=shapeFactory.getShape("RECTANGLE");
shape2.draw();
Shape shape3=shapeFactory.getShape("SQUARE");
shape3.draw();
//使用反射:需要采用强制转化
Rectangle rect = (Rectangle) ShapeFactory.getClass(Rectangle.class);
rect.draw();
Square square = (Square) ShapeFactory.getClass(Square.class);
square.draw();
}
}
(5)结果示例:
调用Circle的draw()方法
调用Rectangle的draw()方法
调用Square的draw()方法
调用Rectangle的draw()方法
调用Square的draw()方法
二、工厂模式与抽象工厂模式:
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题。===>>>>解决:就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
工厂模式语言抽象工厂模式的区别:
(1)抽象工厂的工厂是类;工厂方法的工厂是方法。
(2)抽象工厂模式产出是一个抽象(接口),工厂模式产出是一个产品(实例)。
(3)若添加一个新的产品,抽象工厂模式是创建新工厂(符合“闭合原则”),工厂模式是修改工厂。
工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它和结构型模式,行为型模式是三大主要的设计模式,除了这些之外,还有并发型模式,线程型模式,工厂模式提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象,将创建对象和使用对象分开。
使用说明:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
关键:创建过程在其子类执行。
优点:
1、屏蔽产品的具体实现,调用者只关心产品的接口。
2、将客户和实际创建具体产品的代码分隔开(解耦)
3、个调用者想创建一个对象,只要知道其接口名称就可以了。
4、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
缺点:
每次增加一个产品时,都需要增加一个具体类和修改对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。(使用反射机制可以解决每次增加一个产品时,都需要增加一个对象实现工厂的缺点。)
应用实例:
1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。。
2、Hibernate、mybaits换数据库只需换方言和驱动就可以,不用去管内部是怎么实现转化的。
使用场景:
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
简单的代码示例:
(1)先创建一个产品接口类Shape:
public interface Shape {
void draw();
}
(2)创建产品接口的实现类Circle、Rectangle、Square:
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("调用Circle的draw()方法");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("调用Rectangle的draw()方法");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("调用Square的draw()方法");
}
}
(3)创建一个工厂ShapeFactory ,生成基于给定信息的实体类对象:
public class ShapeFactory {
//使用 getShape方法获取形状类型的对象
public Shape getShape(String shapeType){
if(shapeType==null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
}else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
System.out.println("请输入正确的shapeType类型");
return null;
}
//反射机制:使用反射机制可以解决每次增加一个产品时,都需要增加一个对象实现工厂的缺点
public static Object getClass(Class<? extends Shape> clazz){
Object obj=null;
try{
obj=Class.forName(clazz.getName()).newInstance();
/*
* 1.Class.forName(String className)这个方法传入一个类型的全路径的名字
* (也就是带包的完整名字),会返回一个字节码类型(也就是Class类型)的实例。
* 2.然后再用这个字节码类型的实例clazz调用newInstance()方法
* 会返回一个Object类型的对象。
*/
}catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return obj;
}
}
(4)生产产品:
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory=new ShapeFactory();
//获取Circle的对象,并调用他的draw方法
Shape shape1=shapeFactory.getShape("CIRCLE");
shape1.draw();
Shape shape2=shapeFactory.getShape("RECTANGLE");
shape2.draw();
Shape shape3=shapeFactory.getShape("SQUARE");
shape3.draw();
//使用反射:需要采用强制转化
Rectangle rect = (Rectangle) ShapeFactory.getClass(Rectangle.class);
rect.draw();
Square square = (Square) ShapeFactory.getClass(Square.class);
square.draw();
}
}
(5)结果示例:
调用Circle的draw()方法
调用Rectangle的draw()方法
调用Square的draw()方法
调用Rectangle的draw()方法
调用Square的draw()方法
二、工厂模式与抽象工厂模式:
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题。===>>>>解决:就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
工厂模式语言抽象工厂模式的区别:
(1)抽象工厂的工厂是类;工厂方法的工厂是方法。
(2)抽象工厂模式产出是一个抽象(接口),工厂模式产出是一个产品(实例)。
(3)若添加一个新的产品,抽象工厂模式是创建新工厂(符合“闭合原则”),工厂模式是修改工厂。
相关文章推荐
- C++设计模式-抽象工厂
- 设计模式之JAVA----工厂模式
- 追MM与设计模式的JAVA实现-简单工厂方法
- 设计模式——工厂模式
- C++设计模式之工厂方法模式
- 设计模式 抽象工厂 Abstract Factory
- Java设计模式之工厂模式
- 设计模式学习(四):集中式工厂的实现—简单工厂模式
- 设计模式------工厂模式
- c++设计模式之简单工厂
- Android设计模式之工厂模式
- java设计模式之工厂方法模式
- 设计模式三大基础模式之工厂模式,单例模式,注册树模式
- 深入理解JavaScript系列(28):设计模式之工厂模式
- 设计模式 学习笔记(1)简单工厂模式、策略模式
- 设计模式之工厂模式
- 设计模式学习小结——第一篇 原则和工厂的比较
- php设计模式之简单工厂
- java设计模式——创建型之工厂三兄弟(3)
- 设计模式笔记-创建型模式之三--工厂方法:Factory Method