简单工厂模式

简单工厂模式

我们通过一个例子来看一下未使用简单工厂模式的缺点。

package quedian;

public class Chart {
    public String type;//图表类型
    public Chart(Object[][] data,String type){
        this.type=type;//图表类型
        if(type.equalsIgnoreCase("histogram")){
            //初始化柱状图
        }else if(type.equalsIgnoreCase("pie")){
            //初始化饼状图
        }
    }
    public void display(){
        if(this.type.equalsIgnoreCase("histogram")){
            //显示柱状图
        }else if(this.type.equalsIgnoreCase("pie")){
            //显示饼状图
        }
    }
}

当客户端,通过调用Chart类的构造函数来创建图表对象,根据参数type的不同可以得到不同类型的图表。
但是存在以下缺点:

  1. 代码相对冗长,且大量的条件语句的存在,将影响系统的性能。
  2. Chart类的职责过重,违反了单一职责原则。并且将大量的对象初始化代码写在构造函数将导致构造函数过于庞大,对象创建时需要判断,降低对象创建的效率。
  3. 违反了开闭原则
  4. 客户端只能通过new关键字来直接创建Chart对象,Chart类与客户端耦合度较高,对性的创建和使用无法分离。
  5. 客户端在创建Chart对象之前可能还需要大量的初始化设置。
通过以上,我们开始学习简单工厂模式。
设计思想,基本流程

首先将需要创建的各种不同对象(例如各种不同的Chart对象)的相关代码封装到不同的类中,这些类称为 具体产品类,而将它们公共的代码进行抽象和提取后封装在一个 抽象产品类中,每一个具体产品类都是抽象产品类的子类;然后 提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入的参数不同创建不同的具体产品对象;客户端只需调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。
简单工厂模式(Simple Factory Pattern):
定义一个工厂类,它可以根据参数的不同,返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。
在这里插入图片描述

package com.simpleFactory.Gch;

public class ConcreteProductA extends Product {
    public void methodDiff(){
     System.out.print("创建产品A");
    }
}

package com.simpleFactory.Gch;

public class ConcreteProductB extends Product {
    public void methodDiff(){
System.out.print("创建产品B");
    }
}

package com.simpleFactory.Gch;

public class Factory {
    public static Product getProduct(String args){
        Product product=null;
        if(args.equalsIgnoreCase("A")){
            product=new ConcreteProductA();
        }else if(args.equalsIgnoreCase("B")){
            product=new ConcreteProductB();
        }
        return product;
    }
}

package com.simpleFactory.Gch;

public abstract class  Product {
    public void methodSame(){

    }
    public abstract void methodDiff();
}

用简单工厂模式对我们前面给出的栗子进行重构

在这里插入图片描述

package com.simpleFactory.Gch.Chart;

public class Client {
    public static void main(String args[]){
        Chart chart;
        chart = ChartFactory.getChart("histogram");
        chart.display();
    }
}

package com.simpleFactory.Gch.Chart;

public interface Chart {
    public void display();
}

package com.simpleFactory.Gch.Chart;

public class ChartFactory {
    public static Chart getChart(String type){
        Chart chart=null;
        if(type.equalsIgnoreCase("histogram"))
        {
            chart=new HistogramChart();
            System.out.println("初始化柱状图");
        }else if(type.equalsIgnoreCase("pie")){
            chart=new PieChart();
            System.out.println("初始化饼状图");
        }else if(type.equalsIgnoreCase("line")){
            chart=new LineChart();
            System.out.println("初始化折线图");
        }
        return chart;
    }
}

package com.simpleFactory.Gch.Chart;

public class HistogramChart implements Chart {
public HistogramChart(){
    System.out.println("显示柱状图");
}
public void display(){
    System.out.println("花柱状图");
}
}

package com.simpleFactory.Gch.Chart;

public class LineChart implements Chart {
    public void LineChart(){
        System.out.println("线型图");
    }
  public void display(){
      System.out.println("画线型图");
  }
}

package com.simpleFactory.Gch.Chart;

public class PieChart implements Chart {
    public void PieChart(){
        System.out.println("饼图");
    }
    public void display(){
        System.out.println("画饼图");
    }
}

虽然以上方法解决了一定的问题,但是还存在着违反开闭原则的问题
Sunny软件公司开发人员发现在创建具体Chart对象时,每更换一个Chart对象都需要修改客户端代码中静态工厂方法的参数,客户端代码将要重新编译,这对于客户端而言,违反了“开闭原则”;
因此我们做出了如下修改
在这里插入图片描述

原文地址:https://www.cnblogs.com/gaochunhui/p/11700606.html