文章目录
简单工厂 (不属于GOF 23种设计模式)
定义
指由一个工厂对象决定创建出哪一种产品类的实例
创建型模式,但不属于GOF 23种设计模式
示例
- 接口
public interface Animal {
/**
* 动物吃东西的方法
*/
void eat();
}
- 实例
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗喜欢吃骨头");
}
}
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
- 简单工厂
public class AnimalFactory {
public Animal create(Class<? extends Animal> clazz){
if (null != clazz){
try {
return clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
- 测试
public class SimpleFactoryTest {
public static void main(String[] args) {
Animal animal = new AnimalFactory().create(Dog.class);
animal.eat();
}
}
- 结果
- UML图
在源码中的应用
在JDK中的Calender类
运用到的简单工厂模式,三个创建方法都继承了Calender类
适用场景
1.工厂类负责创建的对象较少
2.客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心.
简单工厂的优缺点
- 优点
1.只需传入一个正确的参数,就可以获取你所需要的对象,无需知道其创建的细节- 缺点
1.工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则
2.不易于扩展过于复杂的产品结构
工厂方法模式
定义
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行
示例
- 实例接口
public interface IAnimal {
void eat();
}
- 具体实例
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗喜欢吃骨头");
}
}
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
- 实例工厂接口
public interface IAnimalFactory {
IAnimal create();
}
- 具体实例工厂
public class DogFactory implements IAnimalFactory {
public IAnimal create() {
return new Dog();
}
}
public class CatFactory implements IAnimalFactory {
public IAnimal create() {
return new Cat();
}
}
- 测试
public class FactoryMethodTest {
public static void main(String[] args) {
IAnimal dog = new DogFactory().create();
dog.eat();
IAnimal cat = new CatFactory().create();
cat.eat();
}
}
- 结果
- UML图
在源码中应用
slf4j的ILoggerFactory
适用场景
创建对象需要大量重复的代码.
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节.
一个类通过其子类来指定创建哪个对象.
工厂方法模式的优缺点
- 优点
用户只需要关心产品对应的工厂,无需关心创建细节
加入新产品符合开闭原则,提高了系统的可扩展性- 缺点
类的个数容易过多,增加了代码结构的复杂程度
增加了系统的抽象性和理解难度
抽象工厂模式
定义
提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类
示例
- 接口
public interface IEat {
void eat();
}
public interface IHobby {
void hobby();
}
接口实现类
public class CatEat implements IEat{
public void eat() {
System.out.println("猫喜欢吃鱼");
}
}
public class CatHobby implements IHobby{
public void hobby() {
System.out.println("猫喜欢睡觉");
}
}
public class DogEat implements IEat{
public void eat() {
System.out.println("狗吃骨头");
}
}
public class DogHobby implements IHobby{
public void hobby() {
System.out.println("狗喜欢乱跑");
}
}
- 抽象工厂
public abstract class AnimalFactory {
public void init(){
System.out.println("初始化基础数据");
}
public abstract IEat createEat();
public abstract IHobby createHobby();
}
- 抽象工厂实现类
public class CatFactory extends AnimalFactory {
public CatFactory(){
super.init();
}
@Override
public IEat createEat() {
return new CatEat();
}
@Override
public IHobby createHobby() {
return new CatHobby();
}
}
public class DogFactory extends AnimalFactory {
public DogFactory(){
super.init();
}
@Override
public IEat createEat() {
return new DogEat();
}
@Override
public IHobby createHobby() {
return new DogHobby();
}
}
- 测试
public class AbstractFactoryTest {
public static void main(String[] args) {
AnimalFactory animalFactory = new CatFactory();
animalFactory.createEat().eat();
animalFactory.createHobby().hobby();
}
}
- 测试结果
- UML图
适用场景
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复代码
提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现.
工厂方法模式的优缺点
- 优点
具体产品在应用层代码隔离,无需关心创建细节
将一个系列的产品族统一到一起创建- 缺点
规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
增加了系统的抽象性和理解难度
简单工厂,工厂方法,抽象工厂的区别
举个例子:
假设我们想要喝苹果果汁,蓝莓果汁
简单工厂是直接将能喝的苹果果汁,蓝莓果汁给我们
工厂方法是将苹果榨汁,蓝莓榨汁机机给我们
抽象工厂则是告诉我们榨汁需要哪些步骤