zoukankan      html  css  js  c++  java
  • OOAD之创建型模式之工厂模式

    首先我们为什么要学习设计模式呢?

    1)模式从经验中总结出来的,经过证实的方案,模式只有在实际系统中经过多次验证之后才能成为模式. 

    2) 提高系统的可维护性, 通过使用设计模式,在系统面临升级和维护时,将把维护成本控制在最低的水平上.
    3) 增加表达能力: 设计模式有很强的语言表述性. 设计模式是对解决方案的总结,使得设计模式能够更好的传达和交流,成为开发人员之间的一种共通语言,从而被更多的开发人员使用,反过来促进设计模式的发展和应用.
    4)帮助我们更好的进行软件设计.

    1 模式的概念:是具有代表性的重复性问题及其解答方案. 

    模式包含的要素:模式的名称  该模式所能解决的问题  解决方案  使用该模式后的效果

       工厂模式

    定义:工厂模式就是集中创建实例对象 

    使用工厂模式的好处:

    1)客户类和实现类分开。消费者任何时候需要某种产  品,只需向工厂请求即可。消费者无须修改就可以接纳新产品

    2)对象的创建由工厂来完成, 类之间的耦合大大减少,变成为类和工厂之间的耦合了.

    3)对象的创建和使用分离,达到解耦合的目的。
    一:简单工厂模式
    eg:工厂生产水果  需要生产苹果,香蕉,梨子
    我们需要建立 苹果类,香蕉类,他们都有一个共同的行为就是生产,所以我们需要把它们共同的行为抽出来。
    写一个最简单的代码:
     
    1 public interface Fruit {
    2     
    3     public void showInfo();
    4 
    5 }
     1 public class Banana implements Fruit{
     2 //香蕉类    
     3       public void showInfo(){
     4           System.out.println("我是一个香蕉");
     5       }
     6 
     7 }
     8 
     9 //苹果类
    10 public class Apple implements Fruit {
    11     
    12     public void showInfo(){
    13         System.out.println("我是一个苹果");
    14     }
    15 
    16 }
    17 
    18 //梨子类
    19 public class Pear  implements Fruit{
    20 
    21     @Override
    22     public void showInfo() {
    23         
    24         System.out.println("我是一个梨子");
    25     }
    26 
    27 }
     1 public class SimpleFactory {
     2     
     3      public  Apple getApple(){
     4           return new Apple();
     5       }
     6       
     7       public Banana getBanana(){
     8           return new Banana();
     9       }
    10      }
    11     
     
     1 public class Test {
     2 
     3     public static void main(String[] args)  {
     4         
     5         
     6        Fruit a = new Apple();
     7         Fruit b = new Banana()    
     8        a.showInfo();
     9       b.showInfo();
    10     }
    11     
    12 }

     如果需要生产梨子,橘子等等其他的水果的话,就需要建立很多的水果类,并且在SimpleFactory需要写得到各种水果的方法,在客户端还需要new各种水果的对象,这样对于开闭原则支持不够!还是根据情况来设计模式!

    二:工厂方法模式
    定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化委托给子类
    还是以水果工厂为例:
    我们需要建立      有一个水果接口,里面存在一个生产水果的方法.     苹果类.    苹果工厂生产苹果的类实现一个工厂生产水果的接口, 一个工厂生产水果的接口。客户端
    建立一种水果的代码:
     1 //水果接口
     2 public interface Fruit {
     3     
     4     public void showInfo();
     5 
     6 }
     7 
     8 
     9 //苹果类实现水果接口
    10 public class Apple implements Fruit {
    11     
    12     public void showInfo(){
    13         System.out.println("我是一个苹果");
    14     }
    15 
    16 }
    17 
    18 
    19 //工厂得到水果接口
    20 public interface IFactoryMethod {
    21 
    22      public Friut getFruit();
    23       
    24 }
    25 
    26 
    27 //苹果工厂实现得到水果接口
    28 
    29 public class AppleFactroy implements IFactoryMethod {
    30 
    31     @Override
    32     public Fruit getFruit() {
    33         return new Apple();
    34     }
    35 
    36 }
    37 
    38 //客户端
    39 public class Test {
    40 
    41     public static void main(String[] args){
    42         
    43     IFactoryMethod fm = new AppleFactroy();
    44     Fruit f = fm.getFruit();
    45     f.showInfo();
    46         
    47     }
    48     
    49 }
     
    三:抽象工厂模式
    为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。(多个产品系列,多个工厂方法一起就构成了抽象工厂模式。)
    在设计抽象工厂模式的时候会涉及到一个词:产品族
    什么事产品族:是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。
    我们还是依然用水果工厂来举例:比如说我们的客户是需要的各种水果还分为北方或是南方的水果;还是使用苹果吧!
    这里我们先分析要怎么去设计这个工厂:  水果接口(显示水果信息), 苹果类, 南方苹果(),北方苹果(), 抽象工厂的角色(接口),具体工厂的角色(南方工厂,北方工厂),客户端
     1 // 水果接口
     2 public interface Fruit {
     3     
     4     public void  showInfo();
     5 
     6 }
     7 
     8 //抽象苹果
     9 public abstract  class Apple implements Fruit {
    10 
    11     public abstract  void showInfo();
    12 
    13 }
    14 
    15 //北方苹果
    16 public class NorthApple extends Apple {
    17 
    18     @Override
    19     public void showInfo() {
    20         System.out.println("北方苹果。。");
    21         
    22     }
    23 
    24 }
    25 
    26 //南方苹果
    27 
    28 public class SouthApple extends Apple {
    29 
    30     @Override
    31     public void showInfo() {
    32         System.out.println("南方苹果。。。");
    33         
    34     }
    35 
    36 }
    37 
    38 //抽象工厂(接口)
    39 
    40 public interface AbstractFactory {
    41     
    42     public Fruit getApple();
    43     
    44     //public Fruit getPear();
    45 
    46 }
    47 
    48 //南方工厂
    49 
    50 public class SouthFactory implements AbstractFactory {
    51 
    52     @Override
    53     public Fruit getApple() {
    54         
    55         return new SouthApple();
    56     }
    57 
    58     /*@Override
    59     public Friut getPear() {
    60        return new SouthPear();
    61     }*/
    62 
    63 }
    64 
    65 //北方工厂
    66 
    67 public class NorthFactory  implements AbstractFactory{
    68 
    69     @Override
    70     public Fruit getApple() {
    71         return new NorthApple();
    72     }
    73 
    74     /*@Override
    75     public Fruit getPear() {
    76         return new NorthPear();
    77     }*/
    78 
    79 }
    80 
    81 //客户端
    82 public class Test {
    83 
    84     public static void main(String[] args) {
    85         
    86         AbstractFactory af = new SouthFactory();
    87         
    88         Fruit f = af.getApple();
    89         
    90         f.showInfo();
    91     }
    92     
    93 }

     这样客户端只需要创建具体工厂的实例,然后调用工厂对象的工厂方法就可以得到所需要的产品对象。

    其优点:

         分离接口和实现

          客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。

    其缺点: 

        不太容易扩展新的产品

      如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。

    这样我们要增加水果种类的时候,只需要增加各类抽象水果,各类南方水果类,各类北方水果类。再到南北方工厂中增加得到增加水果的方法。

    最后:

     无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。
    什么时候该使用什么模式,我也不太清楚,还需要大家去实践,也要看客户有怎样的要求!
     
     
     
  • 相关阅读:
    springboot使用MockMvc测试controller
    MySQL5.6版本之后设置DATETIME类型自动更新
    MAVEN打包时跳过Junit测试
    没看这篇干货,别和我说你会IDEA Debug
    java通过HtmlUnit工具和J4L实现模拟带验证码登录
    Vue+Java实现在页面树形展示文件目录
    exceptions: django2.2/ mysql ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3
    linux 软连接的使用
    Linux pip命令报错 -bash: pip: command not found
    MySQL使用命令导出/导入数据
  • 原文地址:https://www.cnblogs.com/hellokitty1/p/4637597.html
Copyright © 2011-2022 走看看