您的位置:首页 > 其它

设计模式之工厂模式

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)若添加一个新的产品,抽象工厂模式是创建新工厂(符合“闭合原则”),工厂模式是修改工厂。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息