设计模式(一)之深入分析工厂设计模式

简单工厂设计模式(Simple Factory Pattern)

指的是由一个工厂对象来决定创建出哪一类产品种类的实例.

简单工厂示例

创建一个工厂接口:

package com.zwx.service;

public interface IFactory {
	public void create();
}

创建一个产品接口:

package com.zwx.service;

public interface IProduct {
	public void test();
}

创建产品A:

package com.zwx.service.impl;

import com.zwx.service.IProduct;

public class ProductA implements IProduct {
	public void test() {
		System.out.println("===test==ProductA===");
	}
}

创建产品B:

package com.zwx.service.impl;

import com.zwx.service.IProduct;

public class ProductB implements IProduct {
	public void test() {
		System.out.println("===test==ProductB===");
	}
}

工厂实现类,实现了创建对象具体方法

package com.zwx.service.impl;

import com.zwx.service.IProduct;

public class SimpleFactory{
	public IProduct create(String name){
		if("A".equals(name)){
			return new ProductA();
		}else if("B".equals(name)){
			return new ProductB();
		}
		return null;
	}

测试类

package com.zwx.controller;

import com.zwx.service.IProduct;
import com.zwx.service.impl.SimpleFactory;

public class TestFactory1 {
	public static void main(String[] args) {
		SimpleFactory simpleFactory = new SimpleFactory();
		IProduct procuct = simpleFactory.create("A");
		procuct.test();
	}
}

上面就基本上实现了一个简单工厂模式,但是我们发现,假如我们要增加一个产品C,那么我们就需要去修改创建工厂实现了类,这就违背了软件设计的开闭原则,所以,我们可以对CreateFactory类利用反射进行改进。
改进后的工厂实现类

package com.zwx.service.impl;

import com.zwx.service.IProduct;

public class SimpleFactory {
	public IProduct create2(Class<? extends IProduct> clazz) throws InstantiationException, IllegalAccessException{
		if(null == clazz){
			return null;
		}
		return clazz.newInstance();
	}
}

测试类:

package com.zwx.controller;

import com.zwx.service.IFactoryMethod;
import com.zwx.service.IProduct;
import com.zwx.service.impl.ProductCCFactory;
import com.zwx.service.impl.ProductCFactory;

/**
 * 工厂方法测试
 * @author zwx
 */
public class TestFactory2 {
	public static void main(String[] args) {
//		IFactoryMethod factory = new ProductCFactory();
//		IProduct product = factory.create();
//		product.test();
		
		IFactoryMethod factory2 = new ProductCCFactory();
		IProduct product2 = factory2.create();
		product2.test();
	}
}

简单工厂模式适用场景

简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心

简单工厂模式缺点

假如每种产品创建不仅仅只是实例化一个对象,还有其他逻辑需要处理,那么我们无法直接使用一句反射,避免不了写很多if(亦或者用switch循环),这样的话每新增一个产品我们都需要修改工厂实现类,随着产品链越来越丰富,工厂的职责会变得越来越多,久而久之会越来越难以维护。

工厂方法设计模式(Fatory Method Pattern)

工厂方法模式是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个对象,工厂方法让类的实例化推迟到子类中进行,在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符合开闭原则。

创建一个工厂接口,注意这里和简单工厂的区别是接口内方法有返回值

package com.zwx.service;
public interface IFactoryMethod {
	public IFactoryMethod create();
}

创建一个产品C类

package com.zwx.service.impl;

import com.zwx.service.IProduct;

public class ProductC implements IProduct {
	public void test(){
		System.out.println("===test==ProductC===");
	}
}

创建一个产品C工厂类

package com.zwx.service.impl;

import com.zwx.service.IFactoryMethod;
import com.zwx.service.IProduct;

public class ProductCFactory implements IFactoryMethod {
	public IProduct create() {
		return new ProductC();
	}
}

最后,添加测试类

package com.zwx.controller;

import com.zwx.service.IFactoryMethod;
import com.zwx.service.IProduct;
import com.zwx.service.impl.ProductCFactory;

public class TestFactory2 {
	public static void main(String[] args) {
		IFactoryMethod factory = new ProductCFactory();
		IProduct product = factory.create();
		product.test();
	}
}

如此就成功创建了对象C,假如要增加对象D,那么我们只需要新增一个对象C类和其对应的一个工厂类即可,不需要去修改原有的工厂类,符合了开闭原则。

工厂方法模式适用场景

1、创建对象需要大量重复的代码。
2、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
3、一个类通过其子类来指定创建哪个对象。

工厂方法模式缺点

1、类的个数容易过多,增加复杂度。
2、增加了系统的抽象性和理解难度

抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

抽象工厂示例

创建一个抽象接口:

package com.zwx.service;

public interface IAbstractFactory {
	IApple createApple();
	IOrange createOrange();
}

创建两个产品接口:

package com.zwx.service;

public interface IApple {
	void eatApple();
}
package com.zwx.service;

public interface IOrange {
	void eatOrange();
}

假设现在有一个农场要去生产这两种产品,建立如下两个类:

package com.zwx.service.impl;

import com.zwx.service.IApple;

public class Farm1Apple implements IApple {
	public void testApple() {
		System.out.println("=====farm1==testApple");
	}
}
package com.zwx.service.impl;

import com.zwx.service.IOrange;

public class Farm1Orange implements IOrange{
	public void testOrange() {
		System.out.println("=====farm1==testOrange");
	}
}

接下来创建一个农场1的具体工厂类:

package com.zwx.service.impl;

import com.zwx.service.IAbstractFactory;
import com.zwx.service.IApple;
import com.zwx.service.IOrange;

public class Farm1AbstractFactory implements IAbstractFactory{

	public IApple createApple() {
		return new Farm1Apple();
	}

	public IOrange createOrange() {
		return new Farm1Orange();
	}
}

最后再建立一个测试类测试:

package com.zwx.controller;

import com.zwx.service.impl.Farm1AbstractFactory;

public class TestFactory3 {
	public static void main(String[] args) {
		Farm1AbstractFactory factory = new Farm1AbstractFactory();
		factory.createApple().testApple();
		factory.createOrange().testOrange();
	}
}

此时,如果有一个农场2又要来生产Apple和Orange,那么再新增两个对应的产品类以及一个具体工厂类即可实现。

抽象工厂使用场景

当我们有一系列产品(如上面的Apple,Orange)。而这一系列产品每种产品又需要具有不同的创建方法(如上种植Apple和种植Orange方法肯定是不同的需要不同的方法实现)。

抽象工厂缺点

1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂
的接口。
2、增加了系统的抽象性和理解难度。

猜你喜欢

转载自blog.csdn.net/zwx900102/article/details/89811676