美文网首页
工厂模式

工厂模式

作者: AnduinLothar | 来源:发表于2018-04-16 23:51 被阅读0次

    1.简单工厂模式

    假如要设计一个类,根据用户输入参数的不同,产生不同的对象。
    那么可以这样写:

    public class Chart{
        private String type;
        public Chart{Object[][] data,String type){
            this.type=type;
            if(type.equalsIgnoreCase("aaa")){
                // 第一种类型
            }else if(type.equalsIgnoreCase("bbb")){
                // 第二种类型
            }else if(type.equalsIgnoreCase("ccc")){
                // 第三种类型
            }
        }
        public void display(){
            if(this.type.equalsIgnoreCase("aaa")){
                
            }else if (this.type.equalsIgnoreCase("bbb")){
                
            }else if (this.type.equalsIgnoreCase("ccc")){
                
            }
        }
    }
    

    以上代码的缺点
    1.过多的if else 使得代码很冗余
    2.Chart类的职责过重,违反了单一原则
    3.需要增加新的type时 需要更改代码,违反开闭原则
    4.与使用者耦合度太高
    5.每种type的chart都需要进行初始化,代码重复

    这种情况下可以使用简单工厂模式:

    简单工厂模式 又称 静态工厂模式
    定义一个工厂类,根据参数的不同返回不同的 产品实例 ,产品实例有着共同的父类,即抽象的产品类。

    要点:

    传入一个正确的参数就可以获得一个对应的产品,而且无需知道创建细节。
    修改后的代码 可以这么写:

    abstract class Chart{
        abstract void methodDiff();//每个type的chart的特有方法
        public void methodSame(){  //所有type的chart的相同方法
            
        }
    }
    class ChartA extends Chart{     //具体的chartA
        public void methodDiff(){
            
        }
    }   
    class ChartB extends Chart{     //具体的chartB
        public void methodDiff(){
            
        }
    }
    class ChartFactory{
        public static Chart getChart(String type){
            Chart chart=null;
            if(type.equalsIgnoreCase(“aaa”)){
                chart=new ChartA();
            }else if(type.equalsIgnoreCase("bbb")){
                chart=new ChartB();
            }
            return chart;
        }
    }
    
    // 客户端获取产品时 直接调用
    Chart chart=ChartFactory.getChart("aaa");
    

    总结

    将对象的创建和使用分离
    优点
    1.对象的创建 和 使用分离

    2.用户不需要知道创建的具体对象

    3.可以引入配置文件,可以在不改变代码的情况下,添加或更换新的产品类

    缺点

    工厂类职责过重,产品类过多是会导致工厂类过于复杂。
    违反开闭原则。

    使用场景

    产品类不多
    客户端并不关心产品类如何创建

    2.工厂方法模式

    interface Product{
        public void Method();
    }
    class ProductA implements Product{
        public void Method(){
            //产品A
        }
    }
    class ProductB implements Product{
        public void Method(){
            //产品B
        }
    }
    // 若A B产品初始化都需要 经历复杂的初始化
    class ProductFactory{
        public static Product getProduct(String type){
            Product p=null;
            if(type.equals("a")){
                // 消耗大量资源的操作
                p=new ProductA();
            }else {
                // 消耗大量资源的操作
                p=new ProductB();
            }
            return p;
        }
    }
    // 大量操作写到构造方法中就不合适
    

    此时可以使用 工厂方法模式。
    又名 虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern),定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。

    interface Factory {
        public Product getProduct();
    }
    class AFactory implements Factory {
        public Product getProduct(){
            // 消耗大量资源的操作 
            return new ProductA();//亦可以 不返回对象,直接在此调用Method()方法,即对使用者隐藏了工厂方法 即隐藏了具体的对象。也可以通过配置文件写入类名的方法,在此解析配置文件加载类名 然后反射产生对象
        }   
    }
    class BFactory implements Factory {
        public Product getProduct(){ //亦可以弄几个多态方法,来生成产品
            // 消耗大量资源的操作
            return new ProductB(); 
        }
    }
    

    工厂方法模式的总结:
    优点
    1. 有新产品时,只需添加新的产品类和工厂类,无需修改之前的代码 符合 开闭原则
    2. 工厂类 和 产品类 都可以进行多态设计, 工厂可以自己确定创建哪个产品
    3. 可以向调用者隐藏具体产品类,用户不知道到底创建了哪一个产品类。用户只关心对应的工厂,

    缺点

    1. 需要引入抽象层,用户均使用抽象层的定义
    2. 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类

    3.抽象工厂模式

    工厂方法模式 的情况下,每个工厂只生成一种产品。但是假如一个工厂要生成n种产品,而且有很多工厂时,那么 工厂方法模式 便不再合适。

    此时可以使用抽象工厂方法。

    若有 m个工厂,每个工厂都会生成相同的n种产品 。若按照一个工厂一种产品的想法,则需 m*n个工厂。

    m个工厂,每个工厂称为一个产品族。
    n种产品,称为n个产品等级。
    

    抽象工厂方法的思路是:

        AbstractFactory 定义生成这n种产品的方法,
            | ProductA  createProductA();
            | ProductB  createProductB();
            | ProductC  createProductC();
            
        AbstractProduct  抽象的产品
        
        ConcreteFactoryA  extends AbstractFactory   具体工厂A
            |  ProductA  createProductA();
            |  ProductB  createProductB();
            |  ProductC  createProductC();
        ConcreteFactoryB  extends AbstractFactory   具体工厂B
            |  ProductA  createProductA();
            |  ProductB  createProductB();
            |  ProductC  createProductC();
    

    即 定义m个工厂,均继承自抽象工厂,所以实现了构造各种产品的方法,产生了这n中产品等级的所有产品。这种写法,则需 m个工厂。

    总结:
    优点 :

    1. 抽象工厂模式隔离了具体类的生成,改变工厂类很容易。
    2. 保证客户端使用的是同一个产品族的对象,即同一个工厂的产品
    3. 增加新的产品族非常容易, 符合开闭原则

    缺点:
    增加新产品不方便,不符合开闭原则

    相关文章

      网友评论

          本文标题:工厂模式

          本文链接:https://www.haomeiwen.com/subject/vnmykftx.html