• 我的Java设计模式-工厂方法模式


    女朋友dodo闹脾气,气势汹汹的说“我要吃雪糕”。笔者心里啊乐滋滋的,一支雪糕就能哄回来,不亦乐乎?!

    但是,雪糕买回来了,她竟然说“不想吃雪糕了,突然想吃披萨”。呵呵了,憋了一股劲“没问题”,又屁颠屁颠的去把披萨买回来。

    世事难料,dodo同学又放大招了,“披萨太上火了,我要吃芝士蛋糕”。

    这时候,工厂方法模式该上场了,使用它可以完美的解决不断的产品变更。工厂方法模式是怎么样的?而工厂模式又是怎样解决产品变更呢?一起来看看...

    一、工厂方法模式

    定义

      定义一个创建对象的工厂接口,工厂方法将实例化推迟到子类中。

    定义总是抽象的,先放出工厂方法模式的UML图如下所示:

    工厂方法模式UML.png

    从上图可以看出,工厂方法模式涉及到以下四个角色的概念:

      - 抽象工厂角色:工厂方法模式的核心,创建产品的工厂类必须实现该接口。

      - 具体工厂角色:该角色实现了抽象工厂接口,具体如何创建产品类就是在该实现类完成。

      - 抽象产品角色:所有产品类的超类,负责实现产品共性的抽象定义。

      - 具体产品角色:该角色实现了抽象产品接口,负责具体的不同产品业务逻辑。

    二、实战

    上代码

    抽象工厂角色代码如下:

    public interface Factory {
    
    	// 传入参数的是产品类型,这里返回产品类的抽象工厂类Product    
    	public Product factory(String productType);
    
    }
    

    这里做出生产雪糕、披萨的工厂,有了工厂才能生产对应的产品,具体工厂角色代码如下:

    // 雪糕的工厂,负责生产雪糕
    public class IceCreamFactory implements Factory {
    
    	@Override
    	public Product factory() {
    		return new IceCream();
    	}
    
    }
    

    上面看到抽象角色Product,看代码:

    public interface Product {
    
    	public void product();
    
    }
    

    具体角色代码如下:

    public class IceCream implements Product {
    
    	@Override
    	public void product() {
    
    		/**
    		 *  具体的业务逻辑
    		 */
    		System.out.println("雪糕做好了!!");
    	}
    
    }
    

    OK,涉及到工厂方式模式系统的代码基本完成,下面看看客户端怎么使用工厂模式,雪糕准备就绪:

    public class Client {
    
    	public static void main(String[] args){
    
    		// 生产雪糕
    		Factory iceCreamFactory = new IceCreamFactory();
    		Product iceCream = iceCreamFactory.factory();
    		iceCream.product();
    
    	}
    
    }
    

    运行客户端代码,结果如下:

    雪糕做好了!!

    扩展

    雪糕的order已经完成!雪糕不吃,吃披萨?OK,现在就做披萨。同样的先实现抽象工厂和抽象产品角色。

    披萨工厂实现如下:

    // 披萨的工厂,负责生产披萨
    public class PizzaFactory implements Factory {
    
    	@Override
    	public Product factory() {
    		return new Pizza();
    	}
    
    }
    

    接下来就是披萨:

    public class Pizza implements Product {
    
    	@Override
    	public void product() {
    		/**
    		 *  具体的业务逻辑
    		 */
    		System.out.println("披萨做好了!!");
    	}
    
    }
    

    现在我们在客户端中实现生产披萨,代码如下:

    public class Client {
    
    	public static void main(String[] args){
    
    		// 生产雪糕
    		Factory iceCreamFactory = new IceCreamFactory();
    		Product iceCream = iceCreamFactory.factory();
    		iceCream.product();
    
    		// 生产披萨
    		Factory pizzaFactory = new PizzaFactory();
    		Product pizza = pizzaFactory.factory();
    		pizza.product();
    	}
    
    }
    

    运行结果如下:

    雪糕做好了!!

    披萨做好了!!

    三、工厂方法模式的优缺点

    优点

    1)优秀的扩展性。假如披萨不想吃了,想吃芝士蛋糕,只需要增加芝士蛋糕的具体工厂和具体产品类,不会影响其他产品的生产。

    2)大降低代码的耦合度,客户端最终得到的是产品本身,而不需要知道和操作产品的生产过程。

    缺点

    1)增加新产品时,需要增加具体的工厂类和具体的产品类,当产品数量多的时候就会造成系统的复杂度增大,也增加了对系统理解的难度。

    四、比较

    跟策略模式对比:问得最多的一个问题。工厂方法模式和策略的模式有什么区别?区别在于,策略模式强调的是提供不同的策略方案,而工厂方法模式强调的是产品本身。

    策略模式接下来也会说到,把策略模式吃透了,回头再跟工厂方法模式对比的时候就恍然大悟了。

    总结

    首先,上一篇的单例模式很多人都给我提了很不错的建议,也在这篇文章中改进了。工厂方式模式的使用率也非常高,掌握它对把握系统架构会有比较大的提升。下一篇要分享的是:建造者模式

    设计模式Java源码GitHub下载:https://github.com/jetLee92/DesignPattern

    AndroidJet的开发之路.jpg

  • 相关阅读:
    [poj] 3068 "Shortest" pair of paths || 最小费用最大流
    [poj] 3686 The Windy's || 最小费用最大流
    [poj] 1235 Farm Tour || 最小费用最大流
    [poj] 3281 Dining || 最大流
    [poj] 3041 Asteroids || 最小点覆盖=最大二分图匹配
    luogu P1072 Hankson 的趣味题
    二分图最佳匹配
    181106 solution
    luogu P2216 [HAOI2007]理想的正方形
    luogu P4362 [NOI2002]贪吃的九头龙
  • 原文地址:https://www.cnblogs.com/AndroidJet/p/7576451.html
Copyright © 2020-2023  润新知