设计模式学习JAVA(三)创建性模式——简单工厂/抽象工厂

参考链接:http://www.runoob.com/design-pattern/abstract-factory-pattern.html

示例代码:https://github.com/jianghan0712/design-pattern

目录

简单工厂

一、综述

二、主要思想

三、示例UML

四、示例代码

五、总结

 

抽象工厂

一、综述

二、主要思想

三、示例UML

四、示例代码

五、总结


简单工厂

一、综述

     非常常用的创造型模式,在Java中随处可见,与反射结合起来用最好了。现实中,如log4j,logpack等便提供了slf4j需要的工厂方法,所以可以方便的构造自己的系统。另一个好处是,创建过程中,可以不对客户端暴露自己的创建逻辑。


二、主要思想

     Factory工厂类提供统一的调用接口,具体实现在各子类中实现。使用反射机制,传给Factory你想要创建对象的Class,工厂最后返回给你实际的对象


三、示例UML

(原图地址:www.runoob.com/design-pattern/factory-pattern.html)

                                      


四、示例代码

    在这个系统中,存在3种角色,要屏蔽Product和User之间的耦合关系

   Product:实际的产品

   Factory:工厂类

   User:实际产品的使用者

统一的产品定义接口

     Sharp.java

public interface Shape {
	void draw();
}

两个实际的产品:

    Rectangle.java 

public class Rectangle implements Shape{

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("this is a rectangle");
	}
}

    Square.java

public class Square implements Shape{

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("this is a square");
	}
}

    工厂类SharpFactory.java

public class SharpFactory {
	//用反射机制实现,创建基于该类的一系列对象。在本例中并无效果,但在实际中非常常见
	public static Object getShape(Class<?> c1) {
		Object en = null;
		try {
			en = c1.newInstance();			
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		return en;		
	}
	
    //普通方法实现
	public static Shape getShape(String type) {
		Shape ret = null;
		if(type.equalsIgnoreCase("square")) {
			ret = new Square();
		}else if(type.equalsIgnoreCase("rectangle")){
			ret = new Rectangle();
		}
		return ret;
	}
}

测试类,分别用两种方法创建对象

Main.java

public class Main {
	public static void main(String[] args) {
		System.out.println("use reflect");
		Square test = (Square)SharpFactory.getShape(Square.class);
		test.draw();
		
		System.out.println("----------------------");
		
		System.out.println("use commom");
		Square test2 = (Square)SharpFactory.getShape("Square");
		test2.draw();
	}
}

五、总结

        适用场景:需要工厂管理的类比较少。如果过多时,会非常难以维护


 

抽象工厂

一、综述

        通常,一个具体的工厂生产一个具体的产品,但有时我们需要一个工厂能够提供多个产品对象,此时,要使用抽象工厂

二、主要思想

        客户端调用的工厂类,实质是多个具体工厂的集合,所以又被称为工厂的工厂。比如示例中,有两个产品族:形状和颜色。提供两种形状:Square和Rectangle,两种颜色:Yellow和Red。也就是有四种对应的工厂方法。但客户端并不直接调用,而是通过另一个工厂类FactoryProducer来统一生产。比如,要求生产红色的正方形,则传入参数red和square,工厂便会调用对应产品的工厂类来生产所需的东西。


三、示例UML

                                


四、示例代码

    两个产品族color和shape;两个产品族的工厂类ColorFactory和ShapeFactory; color下的两个实现类Yellow和red;Shape下的两个实现类Square和Rectangle;一个超级工厂 FactoryProducer;一个测试类Main 

    两个产品族接口定义

    Color.java

public interface Color {
	void fill();
}

    Sharp.java

public interface Shape {
	void draw();
}

    分别定义两个实体类

    color的两个实体

    Red.java

public class Red implements Color{

	@Override
	public void fill() {
		// TODO Auto-generated method stub
		System.out.println("Red:fill() method");
	}
}

    Yellow.java

public class Yellow implements Color{

	@Override
	public void fill() {
		// TODO Auto-generated method stub
		System.out.println("Yellow:fill() method");
	}
}

       两个产品族分别的工厂方法

    ShapeFactory.java

public class ShapeFactory extends AbstractFactory{

	@Override
	public Object getColor(Class<?> color) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object getShape(Class<?> shape) {
		// TODO Auto-generated method stub
		Object en = null;
		try {
			en = shape.newInstance();			
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		return en;		
	}
}

    ColorFactory.java

public class ColorFactory extends AbstractFactory{

	@Override
	public Object getColor(Class<?> color) {
		// TODO Auto-generated method stub
		Object en = null;
		try {
			en = color.newInstance();			
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return en;
	}

	@Override
	public Object getShape(Class<?> shape) {
				
		return null;		
	}
}

    最后,创建两个工厂方法的超级工厂FactoryProducer.java

public class FactoryProducer {
	public static AbstractFactory getFactory(String choice){
	      if(choice.equalsIgnoreCase("SHAPE")){
	         return new ShapeFactory();
	      } else if(choice.equalsIgnoreCase("COLOR")){
	         return new ColorFactory();
	      }
	      return null;
	   }
}

测试类Main.java

public class Main {
	public static void main(String[] args) {
		  //获取形状工厂
	      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
	 
	      //获取形状为 Circle 的对象
	      Shape shape1 = (Square)shapeFactory.getShape(Square.class);
	 
	      //调用 Circle 的 draw 方法
	      shape1.draw();
	 
	      //获取形状为 Rectangle 的对象
	      Shape shape2 = (Rectangle)shapeFactory.getShape(Rectangle.class);
	 
	      //调用 Rectangle 的 draw 方法
	      shape2.draw();
	 
	      //获取颜色工厂
	      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
	 
	      //获取颜色为 Red 的对象
	      Color color1 = (Red)colorFactory.getColor(Red.class);
	 
	      //调用 Red 的 fill 方法
	      color1.fill();
	 
	      //获取颜色为 Green 的对象
	      Color color2 = (Yellow)colorFactory.getColor(Yellow.class);
	 
	      //调用 Green 的 fill 方法
	      color2.fill();
	   
	}
}

五、总结

    适用场景:1.  一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。

                      2.系统中有多于一个的产品族,而每次只使用其中某一产品族。

                      3. 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。

                      4. 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

    优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象

    缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

猜你喜欢

转载自blog.csdn.net/jh19900712/article/details/86154660