一, 引言
园子里有关设计模式的文章可以说数不胜数, 之前也看过很多, 但是其实理解都不深入, 时间一长就忘了. 最好是记录下来, 总结中加深印象, 这里也给刚开始进行开发的同学提个建议, 不要因为自己写的不好而不去写, 谁都是从菜鸟开始的, 不断的总结才能将知识消化成自己的.
现在开始今天的学习.
工厂模式是设计模式中很重要的一个模式, 其中有简单工厂模式(并不能算一个模式), 工厂模式, 抽象工厂模式.
工厂模式, 从名字可以看出, 这是一个创建型的模式, 是用来创建对象. 我们从简单工厂模式开始
二, 简单工厂模式
简单工厂模式其实并不是一个设计模式, 反而比较像一种变成习惯. 为什么会出现简单工厂呢?
当使用 "new" 关键字创建一个对象时, 此时该类就依赖与这个对象, 也就是他们之间的耦合度高, 当需求变化时, 我们就不得不去修改此类的源码.
当我们需要实例化一个类时, 不知道实例化哪个类, 那么我们把这个变化封装起来, 用一个工厂来帮我们创建对象.
这里我想用饭店的例子, 先看类图:
代码实现:
- // 食物接口
- public interface Food {
- // 准备
- void prepare();
- // 烹饪
- void cook ();
- // 打包
- void box();
- }
- // 具体食物 鱼
- public class Fish implements Food {
- public void prepare() {
- System.out.println("洗鱼");
- }
- public void cook() {
- System.out.println("水煮鱼");
- }
- public void box() {
- System.out.println("大碗装鱼");
- }
- }
- // 具体食物类 肉
- public class Meat implements Food {
- public void prepare() {
- System.out.println("切肉");
- }
- public void cook() {
- System.out.println("红烧肉");
- }
- public void box() {
- System.out.println("装肉");
- }
- }
运行
- // 简单工厂
- public class SimpleFoodFactory {
- // 静态创建工厂方法
- public static Food createFood(String type){
- if(!type.isEmpty())
- {
- switch (type){
- case "FISH":
- return new Fish();
- case "MEAT":
- return new Meat();
- default: return null;
- }
- }
- return null;
- }
- }
运行结果:
简单工厂模式很简单, 也很容易理解. 它带来了很多好处
1. 解决了客户端直接依赖于具体对象的问题, 客户端可以消除直接创建对象的责任, 而仅仅是消费产品. 简单工厂模式实现了对责任的分割
2. 代码复用, 其他的客户也可以用这个工厂来创建对象.
但是缺点也很明显, 扩展困难, 一旦添加新菜单, 工厂方法必须修改. 工厂模式为我们解决这个问题.
三, 工厂模式
先看一个结构图:
从这个图中可以看出, 工厂方法中创建对象不再是在一个类中, 每一个具体的产品类都有一个创建工厂, 其唯一的职责就是创建对应的产品, 这是两个平行类层级
给出定义: 定义了一个用于创建对象的接口, 让子类来决定要实例化哪一个类, 工厂方法让类把实例化延迟到其子类.
再改造下上面的例子
增加一个 Creator 接口, 并创建两个制造工厂 FishCreator 和 MeatCreator
- // 工厂基类, 创建食物基类
- public interface Creator {
- Food CreateFoddFactory();
- }
- // 创建鱼工厂
- public class FishCreator implements Creator {
- public Food CreateFoddFactory() {
- return new Fish();
- }
- }
- // 创建肉工厂
- public class MeatCreator implements Creator {
- public Food CreateFoddFactory() {
- return new Meat();
- }
- }
运行
- private static void factory() {
- // 创建工厂
- Creator creator=new MeatCreator();
- // 创建食物
- Food food = creator.CreateFoddFactory();
- if(food!=null){
- food.prepare();
- food.cook();
- food.box();
- }
- }
运行结果:
工厂方法通过将实例化延迟到子类解决了逻辑判断问题, 一旦需要扩展, 只需要再添加一个子类及子类工厂即可, 比如现在想要增加鸭子菜单, 只需要增加一个鸭子类 (Duck) 及一个鸭子工厂 (DuckCreator) 即可.
下面介绍更抽象的抽象工厂模式
四, 抽象工厂模式
工厂模式中一个工厂只创建一个产品, 但是在现实的大厂中一般都是创建一系列产品, 成为产品族, 比如我们上面的例子, 我们餐馆要开分店, 然而每个地方的口味不一样, 有些地方喜欢辣的, 有些则喜欢不辣的, 我们可以设计生产辣产品的工厂及不辣产品的工厂, 那么这个时候就用到抽象工厂模式.
先看图:
再结合之前的代码, 我们进行修改, 先创建一个抽象食物工厂, 再创建辣和不辣的工厂
- // 抽象工厂
- public interface FoodFactory {
- // 创建肉工厂
- Meat createMeat();
- // 创建鱼工厂
- Fish createFish();
- }
- // 制造辣的工厂
- public class HotFoodFactory implements FoodFactory {
- public Meat createMeat() {
- return new HotMeat();
- }
- public Fish createFish() {
- return new HotFish();
- }
- }
- // 不辣的的工厂
- public class NotHotFoodFactory implements FoodFactory {
- public Meat createMeat() {
- return new NotHotMeat();
- }
- public Fish createFish() {
- return new NotHotFish();
- }
- }
再增加辣的肉和不辣的肉
- // 辣的肉
- public class HotMeat extends Meat {
- @Override
- public void cook() {
- System.out.println("红烧辣的肉");
- }
- }
- // 不辣的肉
- public class NotHotMeat extends Meat {
- @Override
- public void cook() {
- System.out.println("红烧不辣的肉");
- }
- }
- // 辣的鱼
- public class HotFish extends Fish {
- @Override
- public void cook() {
- System.out.println("做特别辣的鱼");
- }
- }
- // 不辣的鱼
- public class NotHotFish extends Fish {
- @Override
- public void cook() {
- System.out.println("做不辣的鱼");
- }
- }
运行
- private static void abstractFactory() {
- // 辣工厂创建辣产品
- FoodFactory hotFoodFactoryoodFactory=new HotFoodFactory();
- Fish hotfish = hotFoodFactoryoodFactory.createFish();
- if(hotfish!=null){
- hotfish.prepare();
- hotfish.cook();
- hotfish.box();
- }
- System.out.println("-------------");
- Meat hotMeat = hotFoodFactoryoodFactory.createMeat();
- if(hotMeat!=null){
- hotMeat.prepare();
- hotMeat.cook();
- hotMeat.box();
- }
- }
运行结果:
抽象工厂模式将具体产品的创建延迟到具体工厂的子类中, 这样将对象的创建封装起来, 可以减少客户端与具体产品类之间的依赖, 从而使系统耦合度低, 这样更有利于后期的维护和扩展, 这真是抽象工厂模式的优点所在, 然后抽象模式同时也存在不足的地方. 下面就具体看下抽象工厂的缺点(缺点其实在前面的介绍中以已经涉及了):
抽象工厂模式很难支持新种类产品的变化. 这是因为抽象工厂接口中已经确定了可以被创建的产品集合, 如果需要添加新产品, 此时就必须去修改抽象工厂的接口, 这样就涉及到抽象工厂类的以及所有子类的改变, 这样也就违背了 "开发 -- 封闭" 原则.
知道了抽象工厂的优缺点之后, 也就能很好地把握什么情况下考虑使用抽象工厂模式了, 下面就具体看看使用抽象工厂模式的系统应该符合那几个前提:
一个系统不要求依赖产品类实例如何被创建, 组合和表达的表达, 这点也是所有工厂模式应用的前提.
这个系统有多个系列产品, 而系统中只消费其中某一系列产品
系统要求提供一个产品类的库, 所有产品以同样的接口出现, 客户端不需要依赖具体实现.
一口学完了工厂模式, 休息休息!
来源: https://www.cnblogs.com/yuanqinnan/p/10161785.html