设计模式-工厂方法模式

简介: 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 设计模式

相关文章
|
15天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
18天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
11天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
29 1
|
1月前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
21 3
|
2月前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
2月前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
|
2月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
35 0

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    42
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    54
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    38
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    62
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    57
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    41
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    50
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    106
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    78