【Java设计模式】工厂模式

UML之类图

6大设计原则详解(一)

Java23种设计模式学习笔记【目录总贴】

点咖啡案例

需求:设计一个咖啡店点餐系统。
设计一个咖啡类(coffee),并定义其两个子类(美式咖啡【ameriEanCoffeg】和拿铁咖啡【Lattecoffee】);再设计一个咖啡店类(coffeestore),咖啡店具有点咖啡的功能。

package com.factory;

public abstract class Coffee {
    public abstract String getName();
    public void addSuger(){
        System.out.println("加糖");
    }
    public void addMilk(){
        System.out.println("加奶");
    }

}

package com.factory;

public class AmercianCoffee extends Coffee{
    @Override
    public String getName() {
        return "美式咖啡";
    }

}

package com.factory;

public class LatteCoffee extends Coffee{
    @Override
    public String getName() {
        return "拿铁咖啡";
    }
}

package com.factory;

public class CoffeeStore {
    public Coffee orderCoffee(String type){
        //声明变量
        Coffee coffee = null;
        if(type.equals("Amercian")){
            coffee = new AmercianCoffee();
        }else if("Latte".equals(type)){
            coffee = new LatteCoffee();
        }else{
            throw new RuntimeException("对不起,你所点的咖啡没有");
        }
        coffee.addMilk();
        coffee.addSuger();

        return coffee;
    }
}

package com.factory;

public class Client {
    public static void main(String[] args) {
        CoffeeStore coffeeStore = new CoffeeStore();
        Coffee coffee = coffeeStore.orderCoffee("Amercian");
        System.out.println(coffee.getName());
    }
}

如果再添加一种咖啡,就要修改CoffeeStore的内容

简单工厂模式

public class SimpleCoffeeFactory {
    public Coffee createCoffee(String type){
        Coffee coffee = null;
        if(type.equals("Amercian")){
            coffee = new AmercianCoffee();
        }else if("Latte".equals(type)){
            coffee = new LatteCoffee();
        }else{
            throw new RuntimeException("对不起,你所点的咖啡没有");
        }
        return coffee;
    }
}

工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。

抽象工厂(Abts L.ra cl. FacL.ory)︰提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。。
具体工厂(ConcreteFactory)︰主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
抽象产品(Froduct):定义了产品的规范。描述了产品的主要特性和功能。(咖啡)
具体产品(ConcceLee roducL)︰实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间——对应。(美式咖啡、拿铁咖啡)
在这里插入图片描述
一个具体产品对应一个具体工厂

public class CoffeeStore {
    private  CoffeeFactory coffeeFactory;

    public void setCoffeeFactory(CoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(String type){
        Coffee coffee = coffeeFactory.createCoffee();
        coffee.addSuger();
        coffee.addMilk();
        return coffee;
    }
}

外界创建好具体产品后,通过se方法传给具体具体工厂

小结:
首先,AmercianCoffee、LatteCoffee都有addSuger()、addMilk()的方法、为了避免代码的重复,将这些方法放在Coffee类中。

如何在CoffeeStore类中new AmercianCoffee、LatteCoffee呢?

if(type.equals("Amercian")){
    coffee = new AmercianCoffee();
}else if("Latte".equals(type)){
    coffee = new LatteCoffee();
}else{
    throw new RuntimeException("对不起,你所点的咖啡没有");
}

根据参数新建类,
如果再新增一个咖啡类,就要修改CoffeeStore的代码。

工厂方法模式
优点:
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
缺点:
每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

抽象工厂模式

·抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
具体工厂(Concrei.e Fact.ory)︰主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
抽象产 品( roduct)∶定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
具体产品(Cangxe oEroduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
在这里插入图片描述
抽象工厂

public interface DessertFactory {
    Coffee createCoffee();
    Dessert createDessert();
}

具体工厂

public class AmercianDessertFactory  implements DessertFactory{
    @Override
    public Coffee createCoffee() {
        return new AmercianCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new MatchaMousse();
    }
}
public class ItalyDessertFactory implements DessertFactory{
    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new Trimisu();
    }
}

模式扩展

简单工厂+配置文件解除耦合
可以通过工厂模式+配置文件的方式解除工厂对象和产品对象的耦合。在工厂类中加载配置文件中的全类名,并创建对象进行存储,客户端如果需要对象,直接进行获取即可。

首先,在src目录下创建bean.properties配置文件

amercian =com.config_factory.AmercianCoffee
latte = com.config_factory.LatteCoffee

CoffeeFactory具体工厂类

package com.config_factory;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;

public class CoffeeFactory {

    private static HashMap<String,Coffee> map =  new HashMap<>();

    //加载配置文件,获取配置文件的全类名,并创建该类的对象进行存储
    static {
        //创建Properties对象
        Properties properties = new Properties();

        InputStream inputStream = CoffeeFactory.class.getClassLoader().getResourceAsStream("bean.properties");
        try {
            properties.load(inputStream);
            Set<Object> keys = properties.keySet();
            for (Object key : keys) {
                String className = properties.getProperty((String) key);
                Class clazz = Class.forName(className);
                Constructor constructor = clazz.getConstructor();
                Coffee coffee = (Coffee) constructor.newInstance();
                map.put((String)key,coffee);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public static Coffee createCoffee(String name){
        return map.get(name);
    }
}

JDK源码解析-coJlection.iterator方法

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
简单工厂模式、工厂方法模式、抽象工厂模式、策略模式、单例模式、代理模式、装饰器模式、观察者模式、适配器模式

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值