定义
普通工厂:工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法模式使一个类的实例化延迟到其子类。
抽象工厂:抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类,围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
普通工厂类
案例
需求:
- 我们对骨头,小鱼干,蚯蚓进行添加操作
- 我们对狗,猫,鸭进行喂食操作
实现原理:
需求1:
那我们要定义一个添加接口,让骨头,小鱼干,蚯蚓都实现这个接口;
需求二:
那我们要定义一个喂食接口,让狗,猫,鸭都实现这个接口;
需求一的代码:
/**
* 食物接口
*/
public interface FoodDao {
void insert();
}
/**
* @ClassName BoneImpl
* @Description 骨头实现
* @Date 2022/7/6 12:45
**/
public class BoneImpl implements FoodDao {
@Override
public void insert() {
System.out.println("我是骨头");
}
}
/**
* @ClassName BoneImpl
* @Description 小鱼干实现
* @Date 2022/7/6 12:45
**/
public class FishImpl implements FoodDao {
@Override
public void insert() {
System.out.println("我是小鱼干");
}
}
/**
* @ClassName BoneImpl
* @Description 蚯蚓实现
* @Date 2022/7/6 12:45
**/
public class EarthWormImpl implements FoodDao {
@Override
public void insert() {
System.out.println("我是蚯蚓");
}
}
public class test {
public static void main(String[] args) {
FoodDao dao = new EarthWormImpl();
FoodDao dao1 = new BoneImpl();
FoodDao dao2 = new FishImpl();
dao.insert();
dao1.insert();
dao2.insert();
}
}
调用结果展示
需求二的代码
/**
* 动物类的接口
*/
public interface AnimalDao {
void eat();
}
/**
* @ClassName DogImpl
* @Description 狗的实现类
* @Date 2022/7/6 12:55
**/
public class DogImpl implements AnimalDao {
@Override
public void eat() {
System.out.println("狗正在吃骨头");
}
}
/**
* @ClassName DogImpl
* @Description 猫的实现类
* @Date 2022/7/6 12:55
**/
public class CatImpl implements AnimalDao {
@Override
public void eat() {
System.out.println("猫正在吃小鱼干");
}
}
/**
* @ClassName DogImpl
* @Description 鸭子的实现类
* @Date 2022/7/6 12:55
**/
public class DuckImpl implements AnimalDao {
@Override
public void eat() {
System.out.println("鸭子正在吃蚯蚓");
}
}
public class test {
public static void main(String[] args) {
AnimalDao dao = new DogImpl();
AnimalDao dao1 = new CatImpl();
AnimalDao dao2 = new DuckImpl();
dao.eat();
dao1.eat();
dao2.eat();
}
}
调用结果展示
抽象工厂类
实现原理:
我们把上面的两个需求,抽象为一个是食物类的,一个是动物类的,在接口层上我们在进行一层抽象,把食物和动物都封装到一个大工厂,比如说抽象工厂是一个大的工厂,里面包含了食物类和动物类。食物接口和动物接口是小的工厂,狗爱吃骨头,鱼爱吃小鱼干,鸭子爱吃蚯蚓,可以抽象进行任意组合小的工厂。下面看代码:
/**
* @ClassName AbstractFactory
* @Description 抽象工厂
* @Date 2022/7/6 13:03
**/
public interface AbstractFactory {
AnimalDao getAnimal();
FoodDao getFood();
}
/**
* @ClassName DogBoneImpl
* @Description 狗在吃骨头
* @Date 2022/7/6 13:06
**/
public class DogBoneImpl implements AbstractFactory {
@Override
public AnimalDao getAnimal() {
return new DogImpl();
}
@Override
public FoodDao getFood() {
return new BoneImpl();
}
}
/**
* @ClassName DogBoneImpl
* @Description 猫在吃小鱼干
* @Date 2022/7/6 13:06
**/
public class CatFlshImpl implements AbstractFactory {
@Override
public AnimalDao getAnimal() {
return new CatImpl();
}
@Override
public FoodDao getFood() {
return new FishImpl();
}
}
/**
* @ClassName DogBoneImpl
* @Description 鸭子在吃蚯蚓
* @Date 2022/7/6 13:06
**/
public class DuckEarthWormImpl implements AbstractFactory {
@Override
public AnimalDao getAnimal() {
return new DuckImpl();
}
@Override
public FoodDao getFood() {
return new EarthWormImpl();
}
}
public class test {
public static void main(String[] args) {
AbstractFactory a = new DogBoneImpl();
a.getFood().insert();
a.getAnimal().eat();
AbstractFactory b = new CatFlshImpl();
b.getFood().insert();
b.getAnimal().eat();
AbstractFactory c = new DuckEarthWormImpl();
c.getFood().insert();
c.getAnimal().eat();
}
}
调用结果展示
抽象扩展
需求,如果我们要再给上面的加入食物《草》,和加入动物《马》,怎么办呢?
只需要让草实现食物接口,马实现动物接口,实现抽象工厂即可。看代码:
/**
* @ClassName GrassImpl
* @Description 草的实现
* @Date 2022/7/6 13:46
**/
public class GrassImpl implements FoodDao {
@Override
public void insert() {
System.out.println("我是青草");
}
}
/**
* @ClassName HorseImpl
* @Description 马的实现
* @Date 2022/7/6 13:47
**/
public class HorseImpl implements AnimalDao{
@Override
public void eat() {
System.out.println("马正在吃青草");
}
}
/**
* @ClassName HorseGrassImpl
* @Description 马在吃青草
* @Date 2022/7/6 13:48
**/
public class HorseGrassImpl implements AbstractFactory {
@Override
public AnimalDao getAnimal() {
return new HorseImpl();
}
@Override
public FoodDao getFood() {
return new GrassImpl();
}
}
public class test {
public static void main(String[] args) {
AbstractFactory a = new DogBoneImpl();
a.getFood().insert();
a.getAnimal().eat();
AbstractFactory b = new CatFlshImpl();
b.getFood().insert();
b.getAnimal().eat();
AbstractFactory c = new DuckEarthWormImpl();
c.getFood().insert();
c.getAnimal().eat();
HorseGrassImpl d = new HorseGrassImpl();
d.getFood().insert();
d.getAnimal().eat();
}
}
调用结果展示:
抽象工厂的优点和缺点
优点:
在抽象工厂属性类别不变动的时候,我们添加一个类别,是不需要改动原来代码的,只需要添加类就可以,改动小不方便
缺点
但是如果我们要加入另外的属性类别,比如给各个动物都分配住的地方,那我们要在AbstractFactory 工厂内,加入房子,那实现AbstractFactory工厂的所有类都需要重新加入房子属性