设计模式的学习——工厂模式

创建模式------Factory模式

定义:工厂模式属于创建型的设计模式,他提供了一种创建对象的最佳方式。它主要是为创建对象提供过渡的接口,以便将创建 对象的具体过程屏蔽隔离起来,已达到高灵活性的目的。

工厂模式根据抽象程度的不同可以分成三种:

  1. 简单工厂模式也叫静态工厂模式):实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或者接口)的实例。
  2. 工厂方法模式(也叫多形性工厂):工厂方法是粒度很小的设计模式,因为模式表现只是一种抽象方法。提前定义用于创建对象的接口,让子类决定实例化具体的某个类,即在工厂和产品中间增加接口,工厂不再负责产品的创建,有接口针对不同的条件返回具体的类实例,由具体的类实例去实现。
  3. 抽象工厂模式(也叫工具箱):当有多个抽象角色时使用抽象工厂模式。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体情况下,创建多产品对象。它有具体产品类,每个抽象产品产品类可以派生出多个具体产品类,一个抽象工厂类可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。

为何使用:

工厂模式是我们最常用的模式,它实现了创建者和调用者的分离。工厂模式在java程序系统中可以说是随处可见。那为什么工厂模式如此常用呢?因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A();工厂模式也是用来创建实例对象的,所以以后new时要多动脑子想一想,是否可以考虑使用工厂模式。当然如果使用工厂模式,可能会多做一些工作,但是会给你的系统带来更大的可扩展性和尽量少的修改。也就是说,它的好处在后阶段是可以体现出来的。

用工厂方法代替new操作。将选择实现类,创建对象统一管理和控制。

简单工厂模式实例:

public class SampleFactory {
	//定义一个Car接口
	public interface Car{
		void run();
	}
	//奥迪
	static class Audi implements Car{
		@Override
		public void run() {
			System.out.println("奥迪在路上");
		}
	}
	//比亚迪
	static class Byd implements Car{
		@Override
		public void run() {
			System.out.println("比亚迪在路上");
		}	
	}
	//汽车工厂类,可以创建各种汽车对象
	static class CarFactory{
		public static Car createAudi(){
			return new Audi();
		}
		public static Car createByd(){
			return new Byd();
		}
	}
	//测试
	public static void main(String[] args) {
		
		Car c1=new Audi();
		Car c2=new Byd();
		c1.run();
		c2.run();
		/*
		 * 以上代码总结:我们发现调用者需要和Car Byd Audi三个类打交道,
		 * 如果我们增加奔驰,那么调用者也要新增奔驰类。显然,调用者和三个
		 * 类的耦合性太强了,这违反了开闭原则(对修改关闭,对扩展开放)
		 */
		Car c11=CarFactory.createAudi();
		Car c22=CarFactory.createByd();
		c11.run();
		c22.run();
		/**
		 * 简单工厂的方法总结:调用者只需要知道CarFactory和Car接口就行; 
		 * 至于下面有多少实现类,和调用者无关。当需要车对象时,只需要和
		 * CarFactory打交道,获得新创建的对象即可
		 */	
	}

}

工厂方法模式实例:

public class Factory {
	//抽象的产品类,定义一个Car交通工具类。接口中的所有方法都是静态的
	public interface Car{
		void gotowork();
	}
	/**
	 * 定义实际的产品类,总共定义两个,bike和bus。分别表示不同的交通工具
	 * 因为写在一个文件里,为了在main()方法中可以调用,使用了static
	 */
	static class Bike implements Car{

		@Override
		public void gotowork() {
			System.out.println("骑自行车去上班!");
		}
		
	}
	static class Bus implements Car{

		@Override
		public void gotowork() {
			System.out.println("坐公共汽车上班!");
		}		
	}
	//定义抽象工厂接口
	public interface ICarFactory{
		Car getCar();
	}
	//具体的工厂类,分别为每个具体的产品创建不同的工厂子类
	static class BikeFactory implements ICarFactory{
		@Override
		public Car getCar() {
			return new Bike();
		}
		
	}
	static class BusFactory implements ICarFactory{
		@Override
		public Car getCar() {
			return new Bus();
		}	
	}
	public static void main(String[] args) {
		ICarFactory factory=null;
		//bike   通过工厂类创建具体的实例
		factory=new BikeFactory();
		Car bike =factory.getCar();
		bike.gotowork();
		
		//bus
		factory=new BusFactory();
		Car bus=factory.getCar();
		bus.gotowork();
	}

}

工厂方法模式实例总结分析:

工厂模式的优点:1、一个调用者想要创建一个对象,只要知道其名称就可以了,降低了耦合度。2、扩展性高,如果增加一个产品,只要扩展一个工厂类就可以了。使得代码结构更加的清晰。3、屏蔽产品的具体实现,调用者只关心产品的接口。

工厂模式的缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂(这里可以使用反射机制来避免),使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。所以对于简单对象来说,使用工厂模式反而增加了复杂度。

抽象工厂模式实例:
public class AbatractFactory {
	//定义一个形状的接口
	public interface Shape{
		void draw();
	}
	//创建实现接口的实体类
	static class Rectangle implements Shape{
		@Override
		public void draw() {
			System.out.println("矩形类的draw()方法!");
		}	
	}
	static class Square implements Shape{

		@Override
		public void draw() {
			System.out.println("正方形中的draw()方法!");
		}
	}
	static class Circle implements Shape{

		@Override
		public void draw() {
			System.out.println("圆形中的draw()方法!");
		}
		
	}
	
	//为颜色创建一个接口
	public interface Color{
		void fill();
	}
	//创建实现接口的实体类
	static class Red implements Color{
		@Override
		public void fill() {
			System.out.println("红色类中的fill()方法!");
		}
	}
	static class Green implements Color{

		@Override
		public void fill() {
			System.out.println("绿色类中的fill()方法!");
		}	
	}
	static class Blue implements Color{

		@Override
		public void fill() {
			System.out.println("蓝色类中的fill()方法!");
		}		
	}
	
	//为Color和Shape对象创建抽象类来获取工厂
	static abstract class AbstractFactory{
		abstract Color getColor(String color);
		abstract Shape getShape(String shape);
	}
	
	//创建拓展了AbstractFactory的工厂类,基于给定的信息生成实体类的对象
	static class ShapeFactory extends AbstractFactory{

		@Override
		Color getColor(String color) {
			return null;
		}

		@Override
		Shape getShape(String shapeType) {
			if(shapeType==null){
				return null;
			}
			//equalsIgnoreCase忽略大小写比较字符串
			if(shapeType.equalsIgnoreCase("CIRCLE")){
				return new Circle();
			}else if(shapeType.equalsIgnoreCase("RECTANGLE")){
				return new Rectangle();
			}else if(shapeType.equalsIgnoreCase("SQUARE")){
				return new Square();
			}
			return null;
		}
		
	}
	static class ColorFactory extends AbstractFactory{

		@Override
		Color getColor(String color) {
			if(color==null){
				return null;
			}else if(color.equalsIgnoreCase("red")){
				return new Red();
			}else if(color.equalsIgnoreCase("green")){
				return new Green();
			}else if(color.equalsIgnoreCase("blue")){
				return new Blue();
			}
			return null;
		}

		@Override
		Shape getShape(String shape) {
			// TODO Auto-generated method stub
			return null;
		}
		
	}
	
	//创建一个工厂创造器,通过传递形状或者颜色来获取工厂
	static 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;
		}
	}
	
	//使用FactoryProducer来获取AbstractFactory,通过传递类型信息来获取实体类的对象
	public static void main(String[] args) {
		//通过FactoryProducer工厂构造器获取形状工厂
		AbstractFactory shapeFactory=FactoryProducer.getFactory("shape");
		//通过形状工厂获取形状为 Circle 的对象
	        Shape shape1 = shapeFactory.getShape("CIRCLE");
	        //调用 Circle 的 draw 方法
	        shape1.draw();

	        //获取形状为 Rectangle 的对象
	        Shape shape2 = shapeFactory.getShape("RECTANGLE");
	        //调用 Rectangle 的 draw 方法
	        shape2.draw();
	      
	        //获取形状为 Square 的对象
	        Shape shape3 = shapeFactory.getShape("SQUARE");
	        //调用 Square 的 draw 方法
	        shape3.draw();

	        //获取颜色工厂
	        AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
	        //获取颜色为 Red 的对象
	        Color color1 = colorFactory.getColor("RED");
	        //调用 Red 的 fill 方法
	        color1.fill();

	        //获取颜色为 Green 的对象
	        Color color2 = colorFactory.getColor("Green");
	        //调用 Green 的 fill 方法
	        color2.fill();
	       
	       //获取颜色为 Blue 的对象
	       Color color3 = colorFactory.getColor("BLUE");
	       //调用 Blue 的 fill 方法
	       color3.fill();
	}

}

总结:

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

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

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

工厂模式的适用场景:

  1. 一个对象拥有很多的子类;
  2. 创建某个对象时需要进行许多的额外操作;
  3. 系统后期需要经常的扩展,那把对象实例化的任务交由实现类完成,扩展性好。

面向对象的原则:面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派切割成每一段,将为一段再封装起来(减少段与段之间的耦合联系性),这样就可以将风险分散,以后要是需要修改,只要更改每一段,不会发生牵一动百的事情。

总结:无论是简单工厂模式,工厂方法模式还是抽象工厂模式,他们的本质都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度的复用。究竟使用哪种设计模式要根据业务需求来决定。



猜你喜欢

转载自blog.csdn.net/ToBe_Coder/article/details/80037919
今日推荐