设计模式-工厂方法模式

简介: 1. 简单工厂模式(Simple Factory Parrent)/** * 在讲工厂方法模式之前,先将一个简单工厂模式,这个模式实现了对象和被调用者的解耦,但是依旧有很多问题,工厂方法模式就是 * 从建工工厂模式演变过来的 * *...

1. 简单工厂模式(Simple Factory Parrent)


/**
 * 在讲工厂方法模式之前,先将一个简单工厂模式,这个模式实现了对象和被调用者的解耦,但是依旧有很多问题,工厂方法模式就是
 * 从建工工厂模式演变过来的
 *
 * 简单工厂模式:
 * 		简单工厂模式就是由一个工厂类根据传入的参数决定创建哪一种的产品类
 * 适用场景:
 * 		适用于业务逻辑比较简单的情景
 *
 * 第一步: 假设要实现一个描述动物信息功能,我们知道首先要创建一个抽象类 IAnimal, 然后想具体描述什么动物,
 * 就去继承抽象类,再去添加自己本身独有的属性,我们这里实现一个猫 Cat 和狗 Dog
 *
 * 第二步 : 当我们想去获得这两个动物的信息和特长的时候,需要分别去 new 这两个对象,比较麻烦,当我们想看哪一个动物的信息的时候,
 * 还需要自己去创建对象,我们想的是告诉别人我要看哪个动物的信息,他就给我返回这个动物的信息,这里的别人指的就是"工厂",
 * 接下来我们来实现这个功能,首先需要一个工厂类 AnimalFactory,然后我们写一个测试类 TestFactoryMethod,
 * 我们把具体的获取对象实例的方法交给工厂去做,这样更加符合正常的业务逻辑,但它也有一个问题,比如我们想添加一个动物的信息,
 * 我们需要创建一个动物的具体实现类,还要去工厂中添加信息,当业务逻辑比较复杂的时候,这种做法会让程序变得很混乱,因为一个项目中可能
 * 有几百个工厂,当我们要去实现一个新的功能的时候,可能要修改很多类,这不符合设计模式的六大原则中的开闭原则
 *
 * 所以"简单工厂模式"适用于不会再添加新的功能的小项目中,这种工厂类也被称为全能类,意思是设计的时候就已经考虑好了所有情况
 *
 * Created by Demon-Coffee on 2018/1/13 0013.
 */
public interface IAnimal {

	/**
	 * 动物特长
	 */
	String getSpecialty(String specialty);

	/**
	 * 动物属性
	 */
	String getInfo();
}
/**
 * Created by Demon-Coffee on 2018/1/13 0013.
 */
public class Cat implements IAnimal {

	/**
	 * 猫的特长
	 */
	public String getSpecialty(String specialty) {
		return "我会" + specialty;
	}

	public String getInfo() {
		return "我是一只可爱的小猫咪";
	}
}
/**
 * Created by Demon-Coffee on 2018/1/13 0013.
 */
public class Dog implements IAnimal {

	/**
	 * 狗的特长
	 */
	public String getSpecialty(String specialty) {
		return "我会" + specialty;
	}

	public String getInfo() {
		return "我是一条单身狗";
	}
}
/**
 * Created by Demon-Coffee on 2018/1/13 0013.
 */
public class AnimalFactory {

	/**
	 * 获取动物信息实例
	 * @param animalType 动物类型:dog/cat
	 */
	public static IAnimal getInstance(String animalType) throws Exception {
		switch (animalType.toLowerCase()) {
			case "dog":
				return new Dog();
			case "cat":
				return new Cat();
			default:
				throw new RuntimeException("你要查找的动物没有入库");
		}
	}
}
/**
 * 这样做的好处是,屏蔽了底层的创建过程,使用者只需要关心实现即可,不需要关心对象是怎么创建的
 * 缺点也很明显,耦合性很高,当出现一个新的动物的时候,需要修改工厂类,违反了 "开闭原则",
 * 之后将会通过工厂方法模式来解决 "开闭原则" 问题
 *
 * Created by Demon-Coffee on 2018/1/13 0013.
 */
public class TestSimpleFactory {

	public static void main(String[] args) throws Exception {
		// 我想知道狗的信息
		IAnimal animal = AnimalFactory.getInstance("dog");
		System.out.println(String.format("Dog:%s", animal.getInfo()));
		System.out.println(String.format("Dog:%s", animal.getSpecialty("咬人")));

		// 我想知道猫的信息
		animal = AnimalFactory.getInstance("cat");
		System.out.println(String.format("Cat:%s", animal.getInfo()));
		System.out.println(String.format("Cat:%s", animal.getSpecialty("上树")));

		AnimalFactory.getInstance("pig"); // 这里会报错,因为工厂不支持这个动物的创建
	}

	/*
		程序输出:
		我是一条单身狗
		我会咬人
		我是一只可爱的小猫咪
		我会上树
		Exception in thread "main" java.lang.RuntimeException: 你要查找的动物没有入库
		at com.demon.factoryMethod.example1.AnimalFactory.getInstance(AnimalFactory.java:19)
		at com.demon.factoryMethod.example1.TestFactoryMethod.main(TestFactoryMethod.java:19)
	 */
}

2. 工厂方法模式(Factory Method Parrent)


  • 工厂方法模式是简单工厂模式的加强版,解决了简单工厂模式的一些缺点,比如"开闭原则",它不需要修改原来的代码,只需要添加新的代码就可以了,它的层次结构更加复杂,
    适用于比较复杂的场景
  • 实现原理是对简单工厂模式进行了抽象,抽象类 Factory 将不再负责具体的生产,只是制定一些规则,具体的生产由继承了它的具体工厂类去做,这个时候,其实就是一个具
   体的对象对应一个具体的工厂类,一个抽象类对应一个抽象对象类,添加的代码如下,这样的好处是我们每次增加对象只需要修改对象具体实现类,和具体工厂类这两个类,这样
    有一个缺点就是,逻辑判断放在了客户端,客户端需要修改代码,代码片段如下:
/**
 * 工厂方法模式:
 *		工厂方法模式是简单工厂模式的加强版,解决了简单工厂模式的一些缺点,比如"开闭原则",它不需要修改原来的代码,只需要添加
 *		新的代码就可以了,它的层次结构更加复杂
 * 适用场景:
 * 		比较复杂的场景,比如工厂生产的对象可能会有新增,或删除
 * 实现原理:
 *		对简单工厂模式进行了抽象,抽象类 Factory 将不再负责具体的生产,只是制定一些规则,具体的生产由继承了它的具体工厂类去
 *		做,这个时候,其实就是一个具体的对象对应一个具体的工厂类,一个抽象类对应一个抽象对象类,添加的代码如下,这样的好处是我
 *		们每次增加对象只需要修改对象具体实现类,和具体工厂类这两个类,这样也会有一个缺点就是,逻辑判断放在了客户端,客户端需要
 *		修改代码
 * 第一步:
 * 		将example1中的 Cat,Dog,IAnimal 拷贝过来,然后创建一个工厂接口类 IAnimalFactoryMethod
 * 第二步:
 * 		新建 Dog 的工厂类和 Cat 的工厂类,继承 IAnimalFactoryMethod
 *
 * Created by Demon-Coffee on 2018/1/13 0013.
 */
public interface IAnimalFactoryMethod {

	/**
	 * 生产对象
	 * @param animalType 动物类型:dog/cat
	 */
	IAnimal getInstance(String animalType) throws Exception;
}
public class DogFactoryMethod implements IAnimalFactoryMethod {

	@Override
	public IAnimal getInstance(String animalType) throws Exception {
		if(animalType.toLowerCase().equals("dog")) {
			return new Dog();
		}

		throw new Exception("你要查找的动物没有入库");
	}
}
public class CatFactoryMethod implements IAnimalFactoryMethod {

	@Override
	public IAnimal getInstance(String animalType) throws Exception {
		if(animalType.toLowerCase().equals("cat")) {
			return new Cat();
		}
		
		throw new Exception("你要查找的动物没有入库");
	}
}
/**
 * 这样做的好处是,屏蔽了底层的创建过程,使用者只需要关心实现即可,不需要关心对象是怎么创建的
 * 缺点也很明显,耦合性很高,当出现一个新的动物的时候,需要修改工厂类,违反了 "开闭原则",
 * 之后将会通过工厂方法模式来解决 "开闭原则" 问题
 *
 * Created by Demon-Coffee on 2018/1/13 0013.
 */
public class TestFactoryMethod {

	public static void main(String[] args) throws Exception {
		// 我想知道狗的信息
		DogFactoryMethod dogFactoryMethod = new DogFactoryMethod();
		IAnimal animal = dogFactoryMethod.getInstance("dog");
		System.out.println(String.format("Dog:%s", animal.getInfo()));
		System.out.println(String.format("Dog:%s", animal.getSpecialty("咬人")));

		// 我想知道猫的信息
		CatFactoryMethod catFactoryMethod = new CatFactoryMethod();
		animal = catFactoryMethod.getInstance("cat");
		System.out.println(String.format("Cat:%s", animal.getInfo()));
		System.out.println(String.format("Cat:%s", animal.getSpecialty("上树")));
	}

	/*
		程序输出:
		Dog:我是一条单身狗
		Dog:我会咬人
		Cat:我是一只可爱的小猫咪
		Cat:我会上树
	 */
}

具体代码在 Git:JAVA 设计模式

相关文章
|
10天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
19 0
|
29天前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
37 0
|
3月前
|
设计模式 存储 算法
Java 设计模式最佳实践:三、行为模式
Java 设计模式最佳实践:三、行为模式
|
3月前
|
设计模式 Java
常用设计模式(工厂方法,抽象工厂,责任链,装饰器模式)
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法,观察者模式,策略模式)
38 2
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
6天前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
6天前
|
设计模式 Java
小谈设计模式(9)—工厂方法模式
小谈设计模式(9)—工厂方法模式
|
24天前
|
设计模式 关系型数据库 数据库
【C++ 设计模式 工厂模式对比】深入探索设计模式:工厂方法与抽象工厂的比较与对照
【C++ 设计模式 工厂模式对比】深入探索设计模式:工厂方法与抽象工厂的比较与对照
21 1
|
30天前
|
设计模式 Java Spring
设计模式之工厂方法
设计模式之工厂方法
设计模式之工厂方法
|
1月前
|
设计模式 编译器
解析器模式--设计模式
解析器模式--设计模式
17 0