【设计模式系列】--工厂方法

简介: 在前面的博文,小编介绍了简单工厂方法,今天我们继续来学习设计模式的知识。今天我们来学习一下工厂方法,那么什么是工厂方法呢?工厂方法在实际项目中又是如何应用的呢?工厂方法模式中包含的角色又具有什么样的职责呢?工厂方法和简单工厂模式之间又有着怎样千丝万缕的联系呢?今天这篇博文,小编就围绕这几个问题进行讲解,希望对有需要的小伙伴有帮助,不足之处,还请小伙伴多多指教。

在前面的博文,小编介绍了简单工厂方法,今天我们继续来学习设计模式的知识。今天我们来学习一下工厂方法,那么什么是工厂方法呢?工厂方法在实际项目中又是如何应用的呢?工厂方法模式中包含的角色又具有什么样的职责呢?工厂方法和简单工厂模式之间又有着怎样千丝万缕的联系呢?今天这篇博文,小编就围绕这几个问题进行讲解,希望对有需要的小伙伴有帮助,不足之处,还请小伙伴多多指教。

什么是工厂方法模式

工厂方法模式属于类的创建型模式又称为多态工厂模式,工厂方法模式的意义是定义一个创建产品对象的工作接口,将实际创建工作推迟到子类当中,核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。我们来看一下工厂方法模式的类图,如下所示:


那我们如何使用工厂方法模式呢?以简单工厂模式的demo为例,把src中的全部类都复制粘贴到FactoryMethod工程当中,FruitFactory的代码如下所示:

public class FruitFactory {

	/**
	 * get方法,获得所有产品对象
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws ClassNotFoundException 
	 */
	public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException {
		if(type.equalsIgnoreCase("apple")) {
			return Apple.class.newInstance();
		}else if(type.equalsIgnoreCase("banana")){
			return Banana.class.newInstance();
		}else{
			System.out.println("找不到相关实例化类");
			return null;
			
		}
	
	}
	
}

MainClass的代码如下所示:

public class MainClass {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException{

		Fruit apple = FruitFactory.getFruit("Apple");
		Fruit banana = FruitFactory.getFruit("Banana");
		apple.get();
		banana.get();
		
		
	}
}
这个时候我们需要添加一个新的水果呢?如何进行实现?新建类Pear并实现接口Fruit,代码如下所示:

public class Pear implements Fruit {

	@Override
	public void get() {
		System.out.println("采集梨子");

	}

}
如果我们想在MainClass里面获得一个梨子的对象,我们需要在FruitFactory中添加一个判断,代码如下所示:

public class FruitFactory {

	/**
	 * get方法,获得所有产品对象
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws ClassNotFoundException 
	 */
	public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		if(type.equalsIgnoreCase("apple")) {
			return Apple.class.newInstance();
		}else if(type.equalsIgnoreCase("banana")){
			return Banana.class.newInstance();
		}else if(type.equalsIgnoreCase("pear")){
			return Banana.class.newInstance();
		}else{
			System.out.println("找不到相关实例化类");
			return null;
			
		}
	
	}
	
}
编写MainClass里面的代码,如下所示:

public class MainClass {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException{

		Fruit apple = FruitFactory.getFruit("Apple");
		Fruit banana = FruitFactory.getFruit("Banana");
		Fruit pear = FruitFactory.getFruit("Pear");
		apple.get();
		banana.get();
		pear.get();
		
	}
}
运行效果,运行如下所示:


这样的话,我们通过简单工厂可以实现,如果采用工厂方法该如何实现呢?简单工厂的缺点,我们添加一个产品,需要在FruitFactory里面添加判断,不符合开放封闭原则,工厂方法模式,不需要修改代码,工厂方法定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中,我们来看工厂方法如何实现:删除FruitFactory中的内容,重新编写,如下所示:

public interface FruitFactory{
	public Fruit getFruit();
}
如果要获得苹果,我们需要新建类AppleFactory并实现接口FruitFactory,编写相关代码如下所示:

public class AppleFactory implements FruitFactory {

	public Fruit getFruit(){
		return new Apple();
	}

}
如果要获得香蕉,我们需要新建类BananaFactory并实现接口FruitFactory,编写相关代码部分,如下所示:

public class BananaFactory implements FruitFactory {

	@Override
	public Fruit getFruit() {
		return new Banana();
	}

}
编写MainClass里面的代码,如下所示:

public class MainClass {

	public static void main(String[] args){
		//获得AppleFactory
		FruitFactory ff = new AppleFactory();
		//通过AppleFactory来获得Apple实例对象
		Fruit apple = ff.getFruit();
		apple.get();
		
		//获得BananaFactory
		FruitFactory ff2 = new BananaFactory();
		//通过BananaFactory来获得Banana实例对象
		Fruit banana = ff2.getFruit();
		banana.get();
	}
}
执行,如下所示:


所以,这样的好处在哪儿呢?新添加了一个pear,不需要修改FruitFactory,不需要修改BananaFactory和AppleFactory,我们需要做的是新家类PearFactory类并实现接口FruitFactory,编写相关的代码部分,如下所示:

public class PearFactory implements FruitFactory {

	@Override
	public Fruit getFruit() {
		return new Pear();
	}

}
编写MainClass类,代码如下所示:

public class MainClass {

	public static void main(String[] args){
		//获得AppleFactory
		FruitFactory ff = new AppleFactory();
		//通过AppleFactory来获得Apple实例对象
		Fruit apple = ff.getFruit();
		apple.get();
		
		//获得BananaFactory
		FruitFactory ff2 = new BananaFactory();
		//通过BananaFactory来获得Banana实例对象
		Fruit banana = ff2.getFruit();
		banana.get();
		
		//获得PearFactory
		FruitFactory ff3 = new PearFactory();
		//通过PearFactory来获得Banana实例对象
		Fruit pear= ff3.getFruit();
		pear.get();
	}
}
运行,效果如下所示:


这样是完全符合开放封闭原则的,我们添加一个新的pear,我们不需要修改其她的工程,直接新建就可以,结合上面的类图,我们来看一下模式中包含的各种角色以及职责。

a、抽象工厂(Creator)角色

工厂方法模式的核心,任何工厂类都必须实现这个接口。

b、具体工厂(ConcreteCreator)角色

具体工厂类是抽象工厂的一个实现,负责实例化产品对象。

c、抽象(Product)角色

工厂方法模式所创建的所有对象的父类,她负责描述所有实例所共有的公共接口。

d、具体产品(ConcreteProduct)角色

工厂方法模式所创建的具体实例对象

接着,我们来比较一下工厂方法模式和简单工厂模式,如下所示:

a、工厂方法模式与简单工厂模式在结构上的不同不是很明显,工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
b、工厂模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者共同的抽象父类。
c、当系统扩展需要添加新的产品对象的时候,仅仅需要添加一个具体对象以及具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了开放-封闭原则,而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
d、工厂方法模式退化后可以演变成简单工厂模式。

小编寄语:该博文,小编主要简单的介绍了工厂方法模式,通过一个简单的demo进行讲解,简单工厂模式是属于创建型模式,工厂方法模式属于类的创建型模式又称为多态工厂模式,工厂方法模式的意义是定义一个创建产品对象的工作接口,将实际创建工作推迟到子类当中,核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品编程是一门技术,更是一门艺术,在编写代码的过程中,要牢记可复用、易维护、好扩展,这样,自己才能有所提高,才是真正的软件工程师。

目录
相关文章
|
4月前
|
设计模式 开发者
探讨常见设计模式 - 工厂方法模式的最佳实践和潜在的实施问题
【4月更文挑战第7天】工厂方法模式是创建型设计模式,提供了一种在不指定具体类情况下创建对象的方式。它定义创建对象的接口,允许子类决定实例化哪个类,从而解耦对象的创建和使用。最佳实践包括明确接口、封装创建逻辑、提供扩展点和避免过度使用。然而,过度工程、违反开闭原则、性能影响和依赖管理是可能的问题。通过权衡利弊并遵循最佳实践,工厂方法模式能在适当场景下提升代码灵活性和可扩展性。
46 1
|
4月前
|
设计模式 Java
常用设计模式(工厂方法,抽象工厂,责任链,装饰器模式)
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法,观察者模式,策略模式)
52 2
|
1月前
|
设计模式 XML 存储
【二】设计模式~~~创建型模式~~~工厂方法模式(Java)
文章详细介绍了工厂方法模式(Factory Method Pattern),这是一种创建型设计模式,用于将对象的创建过程委托给多个工厂子类中的某一个,以实现对象创建的封装和扩展性。文章通过日志记录器的实例,展示了工厂方法模式的结构、角色、时序图、代码实现、优点、缺点以及适用环境,并探讨了如何通过配置文件和Java反射机制实现工厂的动态创建。
【二】设计模式~~~创建型模式~~~工厂方法模式(Java)
|
1月前
|
设计模式 uml
设计模式-------------工厂模式之工厂方法模式(创建型)
工厂方法模式是一种创建型设计模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类,从而实现类的实例化推迟到子类中进行,提高了系统的灵活性和可扩展性。
|
4月前
|
设计模式
设计模式-简单工厂和工厂方法
设计模式-简单工厂和工厂方法
|
3月前
|
设计模式 Java
Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)
Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)
|
3月前
|
设计模式 搜索推荐
工厂方法模式-大话设计模式
工厂方法模式-大话设计模式
|
3月前
|
设计模式 新零售 Java
设计模式最佳套路5 —— 愉快地使用工厂方法模式
工厂模式一般配合策略模式一起使用,当系统中有多种产品(策略),且每种产品有多个实例时,此时适合使用工厂模式:每种产品对应的工厂提供该产品不同实例的创建功能,从而避免调用方和产品创建逻辑的耦合,完美符合迪米特法则(最少知道原则)。
67 6
|
3月前
|
设计模式 XML Java
【设计模式】第三篇:一篇搞定工厂模式【简单工厂、工厂方法模式、抽象工厂模式】
三 结尾 如果文章中有什么不足,欢迎大家留言交流,感谢朋友们的支持! 如果能帮到你的话,那就来关注我吧!如果您更喜欢微信文章的阅读方式,可以关注我的公众号
40 5
|
3月前
|
设计模式 Java 关系型数据库
设计模式第2弹:工厂方法模式
type ComputerProduct struct{} // 实现工厂方法 func (computer ComputerProduct) GetInformation() string { return "电脑,官方称呼计算机,主要用于进行数据运算的一台机器。" }
36 4