您现在的位置是:首页 >其他 >【设计模式】工厂模式网站首页其他
【设计模式】工厂模式
简介【设计模式】工厂模式
目录
一、说明
- 1.如果使用对象的时候直接new该对象,就会对该对象耦合严重
- 2.如果要更换对象,所有new对象的地方都需要修改,违背了软件设计原则的开闭原则
- 3.使用工厂生产对象,只需要与工厂打交道
- 4.能与对象解耦,如果要更换对象,直接在工厂里更换该对象
- 5.最大的优点即解耦
二、简单工厂模式
2.1 说明
- 1.简单工厂不是一种设计模式,是一种编程习惯
- 2.简单工厂包括抽象产品、具体产品、具体工厂
- 3.抽象产品:定义了产品的规范,描述了产品的主要特性和功能
- 4.具体产品:实现或者继承抽象产品的子类
- 5.具体工厂:提供了创建产品的方法,调用者通过该方法来创建产品
- 6.后续要加新的产品,得要修改简单工厂的代码,违反了开闭原则
- 7.优点:封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,避免修改客户端代码,如果要实现新产品可以直接修改工厂类,而不需要在原代码中修改,降低了客户端代码修改的可能性,更容易扩展
- 8.缺点:增加新产品还是会修改工厂类的代码,违背了“开闭原则”
2.2 简单工厂代码示例
package com.learning.simple_factory;
public class AProduct extends Product {
@Override
public void sell() {
System.out.println("A产品卖出");
}
}
package com.learning.simple_factory;
public class BProduct extends Product {
@Override
public void sell() {
System.out.println("B产品卖出");
}
}
package com.learning.simple_factory;
public abstract class Product {
public abstract void sell();
}
package com.learning.simple_factory;
/**
* @Author wangyouhui
* @Description 简单工厂
**/
public class SimpleFactory {
public Product getProduct(String type){
if("A".equals(type)){
return new AProduct();
}else if("B".equals(type)){
return new BProduct();
}else{
throw new RuntimeException("未找到对应的产品");
}
}
}
package com.learning.simple_factory;
public class Store {
public static void main(String[] args) {
SimpleFactory simpleFactory = new SimpleFactory();
Product a = simpleFactory.getProduct("A");
a.sell();
Product b = simpleFactory.getProduct("B");
b.sell();
}
}
2.3 静态工厂代码示例
package com.learning.static_factory;
/**
* @Author wangyouhui
* @Description 静态工厂
**/
public class StaticFactory {
public static Product getProduct(String type){
if("A".equals(type)){
return new AProduct();
}else if("B".equals(type)){
return new BProduct();
}else{
throw new RuntimeException("未找到对应的产品");
}
}
}
package com.learning.static_factory;
public class Store {
public static void main(String[] args) {
Product a = StaticFactory.getProduct("A");
a.sell();
Product b = StaticFactory.getProduct("B");
b.sell();
}
}
三、工厂方法模式
3.1 说明
- 1.使用工厂方法模式完全遵循开闭原则
- 2.定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象
- 3.工厂方法使一个产品类的实例化延迟到对应工厂的子类
- 4.工厂方法模式的角色:抽象工厂、具体工厂、抽象产品、具体产品
- 5.抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品
- 6.具体工厂:实现抽象工厂中的抽象方法,完成具体产品的创建
- 7.抽象产品:定义了产品的规范,描述了产品的主要特性和功能
- 8.具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应
- 9.优点:用户只需要知道具体工厂的名称便可以得到所要的产品,无须知道产品的具体创建过程;在新增新的产品时只需要添加具体产品类和对应的具体工厂类,不需要对原工厂进行修改,满足开闭原则
- 10.缺点:每增加一个产品就要增加一个具体产品类和一个具体工厂类,增加了系统的复杂度
3.2 工厂方法代码示例
package com.learning.factory.factory_method;
/**
* @Author wangyouhui
* @Description
**/
public abstract class Product {
public abstract void sell();
}
package com.learning.factory.factory_method;
/**
* @Author wangyouhui
* @Description A产品
**/
public class AProduct extends Product{
@Override
public void sell() {
System.out.println("A产品卖出");
}
}
package com.learning.factory.factory_method;
/**
* @Author wangyouhui
* @Description B产品
**/
public class BProduct extends Product{
@Override
public void sell() {
System.out.println("B产品卖出");
}
}
package com.learning.factory.factory_method;
public interface FactoryMethodFactory {
Product getProduct();
}
package com.learning.factory.factory_method;
/**
* @Author wangyouhui
* @Description A产品工厂
**/
public class AProductFactory implements FactoryMethodFactory{
@Override
public Product getProduct() {
return new AProduct();
}
}
package com.learning.factory.factory_method;
/**
* @Author wangyouhui
* @Description B产品工厂
**/
public class BProductFactory implements FactoryMethodFactory{
@Override
public Product getProduct() {
return new BProduct();
}
}
package com.learning.factory.factory_method;
/**
* @Author wangyouhui
* @Description 商店
**/
public class Store {
private FactoryMethodFactory factoryMethodFactory;
public void setFactoryMethodFactory(FactoryMethodFactory factoryMethodFactory) {
this.factoryMethodFactory = factoryMethodFactory;
}
public void sell(){
this.factoryMethodFactory.getProduct().sell();
}
public static void main(String[] args) {
AProductFactory aProductFactory = new AProductFactory();
BProductFactory bProductFactory = new BProductFactory();
Store store = new Store();
store.setFactoryMethodFactory(aProductFactory);
store.setFactoryMethodFactory(bProductFactory);
store.sell();
}
}
四、抽象工厂模式
4.1 说明
- 1.抽象工厂模式考虑多等级产品的生产
- 2.将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族
- 3.台式机、笔记本、pad都是电脑,是同一个产品等级
- 4.苹果制造的笔记本和手机,是同一个产品族
- 5.抽象工厂模式是工厂方法模式的升级版,工厂方法模式只生产一个等级的产品,抽象工厂模式可生产多个等级的产品
- 6.抽象工厂的角色:抽象工厂、具体工厂、抽象产品、具体产品
- 7.抽象工厂:提供创建产品的接口,包含多个创建产品的方法,可以创建多个不同等级的产品
- 8.具体工厂:实现抽象工厂中所有抽象方法,完成具体产品的创建
- 9.抽象产品:定义产品规范,描述产品主要特征和功能,抽象工厂模式有多个抽象产品
- 10.具体产品:实现抽象产品角色定义的接口,由具体工厂来创建,同具体工厂之间是多对一关系
- 11.优点:当一个产品族中的多个对象被设计成一起工作时,能保证客户端始终只使用同一个产品族中的对象
- 12.缺点:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改
4.2 抽象工厂代码示例
package com.learning.factory.abstract_factory;
interface ChineseFactory {
// 获取货物
Goods getGoods();
// 获取产品
Product getProduct();
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description A工厂
**/
public class AFactory implements ChineseFactory{
@Override
public Goods getGoods() {
return new AGoods();
}
@Override
public Product getProduct() {
return new AProduct();
}
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description B工厂
**/
public class BFactory implements ChineseFactory{
@Override
public Goods getGoods() {
return new BGoods();
}
@Override
public Product getProduct() {
return new BProduct();
}
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description
**/
public abstract class Product {
public abstract void sell();
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description 货物
**/
public abstract class Goods {
public abstract void sell();
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description A货物
**/
public class AGoods extends Goods{
@Override
public void sell() {
System.out.println("A货物卖出");
}
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description B货物
**/
public class BGoods extends Goods{
@Override
public void sell() {
System.out.println("B货物卖出");
}
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Descriptionc 产品
**/
public abstract class Product {
public abstract void sell();
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description A产品
**/
public class AProduct extends Product {
@Override
public void sell() {
System.out.println("A产品卖出");
}
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description B产品
**/
public class BProduct extends Product {
@Override
public void sell() {
System.out.println("B产品卖出");
}
}
package com.learning.factory.abstract_factory;
/**
* @Author wangyouhui
* @Description 示例
**/
public class Store {
public static void main(String[] args) {
AFactory aFactory = new AFactory();
Goods goods1 = aFactory.getGoods();
Product product1 = aFactory.getProduct();
goods1.sell();
product1.sell();
BFactory bFactory = new BFactory();
Goods goods2 = bFactory.getGoods();
Product product2 = bFactory.getProduct();
goods2.sell();
product2.sell();
}
}
五、通过配置获取
package com.learning.factory.config_factory;
/**
* @Author wangyouhui
* @Description
**/
public abstract class Product {
public abstract void sell();
}
package com.learning.factory.config_factory;
/**
* @Author wangyouhui
* @Description A产品
**/
public class AProduct extends Product {
@Override
public void sell() {
System.out.println("A产品卖出");
}
}
package com.learning.factory.config_factory;
/**
* @Author wangyouhui
* @Description B产品
**/
public class BProduct extends Product {
@Override
public void sell() {
System.out.println("B产品卖出");
}
}
aProduct=com.learning.factory.config_factory.AProduct
bProduct=com.learning.factory.config_factory.BProduct
package com.learning.factory.config_factory;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;
public class ProductFactory {
//加载配置文件,获取配置文件中配置的全类名,并创建该类的对象进行存储
//1.定义容器对象存储对象
private static HashMap<String, Product> map = new HashMap<>();
//2.加载配置文件,只需要加载一次
static{
//3.创建Properties对象
Properties properties = new Properties();
//4.调用load方法进行配置文件的加载
InputStream is = ProductFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
properties.load(is);
//5.从properties集合中获取全类名并创建对象
Set<Object> set = properties.keySet();
for(Object key: set){
String className = properties.getProperty((String) key);
//通过反射技术创建对象
Class clazz = Class.forName(className);
Product product = (Product) clazz.newInstance();
//将名称和对象存储在容器中
map.put((String)key, product);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Product createProduct(String name){
return map.get(name);
}
public static void main(String[] args) {
Product aProduct = ProductFactory.createProduct("aProduct");
Product bProduct = ProductFactory.createProduct("bProduct");
aProduct.sell();
bProduct.sell();
}
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。