Java设计模式之工厂模式(2)
程序员文章站
2024-01-21 17:47:58
...
往期博客-----> Java设计模式之单例模式(1)
工厂模式也是我们经常使用的23种模式之一,之前我们使用Mybatis时获取SqlSession对象就使用到了工厂模式,接下来我们学习一下工厂模式.
1.字面意思
- 既然翻译过来是工厂模式,那么肯定其核心思想和工厂这个事务有些千丝万缕的关系,工厂就是产生产品的地方,我们给它原材料,然后加工给我们产品,这就是工厂干的事.
2.总体认识工厂模式的三种分类
类型 | 意义 |
---|---|
简单工厂 | 一个工厂类根据传入的参量决定创建出哪一种产品类的实例 |
抽象工厂 | 创建相关或依赖对象的家族,而无需明确指定具体类。 |
工厂方法 | 定义一个创建对象的接口,让子类决定实例化那个类 |
3.简单工厂模式(静态工厂方法模式)
- 定义:
在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
- 通俗小故事来解释:
我们定义一个动物基因工厂,给我们动物的基因我们就可以产生对应动物的个体出来,比如一条狗的基因给我工厂加工,会产生一条狗,一只猫的基因产生一只猫,我们可以通过不同的参数(动物基因)来返回对应的实例(具体一个动物),但一般我们创建的都有一个共同父类(动物)
- 具体代码实现:
- 我们定义一个接口Ieat里面有一个eat()方法,因为动物都会吃,然后我们定义三种动物dog,cat,mouse三个类来实现这个接口:
interface Ieat{
void eat();
}
class Dog implements Ieat{
@Override
public void eat() {
System.out.println("狗狗啃骨头");
}
}
class Cat implements Ieat{
@Override
public void eat() {
System.out.println("猫咪吃老鼠");
}
}
class Mouse implements Ieat{
@Override
public void eat() {
System.out.println("老鼠吃大米");
}
}
- OK,重点来了,我们的基因工厂根据输入的参数来生产对应的实例产品,现在我们来写工厂类:
class GeneFactory{
//根据传入的动物来返回对应的动物对象实例
public Ieat getEat(String animalType){
if (animalType==null){
return null;
}
if (animalType.equalsIgnoreCase("DOG")){
return new Dog();
} else if(animalType.equalsIgnoreCase("CAT")){
return new Cat();
} else if (animalType.equalsIgnoreCase("MOUSE")){
return new Mouse();
}
return null;
}
}
- 接下来我们使用简单工厂模式来测试一下:
public class Mytest02 {
public static void main(String[] args) {
Ieat dog = new GeneFactory().getEat("dog");
dog.eat();
Ieat cat = new GeneFactory().getEat("cat");
cat.eat();
Ieat mouse = new GeneFactory().getEat("mouse");
mouse.eat();
}
}
- 结果实现截图:
4.抽象工厂模式(Abstract Factory Pattern)
- 定义:
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
- 通俗解释一波:
还是基因工厂,简单工厂只是产生狗,猫这些大种类动物,没有产生哈士奇,拉布拉多等具体的狗种类,而超级基因工厂会先产生一个关于狗基因的工厂,再通过这个狗基因工厂来生产出特定的狗品种,比如哈士奇,拉布拉多.
- 代码实现.
- 首先我们的抽象工厂可以产生狗基因工厂(DogGeneFactory)和猫基因工厂(CatGeneFactory),然后基因工厂有一个方法获取特定种类的品种方法,狗工厂为getDogType(),猫工厂getCatType().对应工厂再根据传入的参数生产对应的对象实例.
- 第一步,创建所有狗都会的吃骨头的接口Ieatbone,和猫会吃老鼠的接口Ieatmouse:
interface Ieatbone{
void etaBone();
}
interface Ieatmouse{
void eatmouse();
}
- 第二步,写一个哈士奇类和拉布拉多类实现这个吃骨头接口,以及波斯猫和短耳猫实现吃老鼠接口.
class Husky implements Ieatbone{
@Override
public void etaBone() {
System.out.println("哈士奇吃骨头");
}
}
class Labrador implements Ieatbone{
@Override
public void etaBone() {
System.out.println("拉布拉多吃骨头");
}
}
class Persian implements Ieatmouse{
@Override
public void eatmouse() {
System.out.println("波斯猫吃老鼠");
}
}
class ShortCat implements Ieatmouse{
@Override
public void eatmouse() {
System.out.println("短耳猫吃老鼠");
}
}
- 第三步:定义超级基因工厂(SuperGeneFactory抽象类),定义两个抽象方法获取对应基因工厂的方法:
abstract class SuperGeneFactory{
public abstract Ieatbone getDogType(String dogtype);
public abstract Ieatmouse getCatType(String cattype);
}
- 第四步:写狗基因工厂和猫基因工厂来继承抽象类,实现方法:
class DogGeneFactory extends SuperGeneFactory{
@Override
public Ieatbone getDogType(String dogtype) {
if (dogtype == null){
return null;
} else if(dogtype.equalsIgnoreCase("Husky")){
return new Husky();
} else if (dogtype.equalsIgnoreCase("Labrador")){
return new Labrador();
}
return null;
}
@Override
public Ieatmouse getCatType(String cattype) {
return null;
}
}
class CatGeneFactory extends SuperGeneFactory{
@Override
public Ieatbone getDogType(String dogtype) {
return null;
}
@Override
public Ieatmouse getCatType(String cattype) {
if (cattype == null){
return null;
} else if(cattype.equalsIgnoreCase("Persian")){
return new Persian();
} else if (cattype.equalsIgnoreCase("ShortCat")){
return new ShortCat();
}
return null;
}
}
- 第五步:通过工厂生成器(FactoryBuild)来获取指定种类的基因工厂:
class FactoryBuild{
public static SuperGeneFactory getFactoryType(String factoryTppe){
if (factoryTppe == null){
return null;
} else if (factoryTppe.equalsIgnoreCase("DOG")){
return new DogGeneFactory();
} else if(factoryTppe.equalsIgnoreCase("Cat")){
return new CatGeneFactory();
}
return null;
}
}
- 第六步:测试:
public class Mytest02 {
public static void main(String[] args) {
//1.获取狗基因工厂
SuperGeneFactory dogFactory = FactoryBuild.getFactoryType("dog");
//2.获取猫基因工厂
SuperGeneFactory catFactory = FactoryBuild.getFactoryType("cat");
//3.生产哈士奇
Ieatbone husky = dogFactory.getDogType("husky");
husky.etaBone();
//4.生产拉布拉多
Ieatbone labrador = dogFactory.getDogType("Labrador");
labrador.etaBone();
//5.生产波斯猫
Ieatmouse persian = catFactory.getCatType("Persian");
persian.eatmouse();
//6.生产短耳猫
Ieatmouse shortCat = catFactory.getCatType("ShortCat");
shortCat.eatmouse();
}
}
- 结果:
- 缺点和优点:
优点 | 缺点 |
---|---|
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。 | 产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。 |
5.工厂方法模式
- 创建抽象工厂类,定义具体工厂的公共接口;
- 创建抽象产品类 ,定义具体产品的公共接口;
- 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
- 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
- 外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例.
上一篇: 设计模式(2):工厂模式
下一篇: 《设计模式》学习笔记3——工厂模式