设计模式-工厂模式

2018-08-20  本文已影响0人  菜鸟超

抽象工厂模式:正如其名字一样,非常抽象,这啥概念的我也不多说了,但是抽象工厂模式的功能却十分强大。下面我主要通过对比三种工厂模式来进行学习。

1.简单工厂模式 (Simple Factory)

定义:只有一个工厂类,通过想创建方法中传入不同的参数,来生产不同的产品。

首先定义一个产品类的共同接口


public interface Product {
    //声明类所需继承的共同接口,也可以是抽象类
}

产品类A

public class ProductA implements Product {
    public ProductA() {
        System.out.println("ProductA");
    }
}

产品类B

public class ProductB implements Product {
    public ProductB() {
        System.out.println("ProductB");
    }
}

工厂类

public class Factory {
    //可以在工厂类中添加任何你所需要的逻辑
    public static Product create(String str)
    {
        //生成ProductA
        if(str.equalsIgnoreCase("ProductA"))
        {
            return new ProductA();
        }
        else
            //生成ProductB
            if(str.equalsIgnoreCase("ProductB"))
            {
                return new ProductB();
            }
        return null;
    }

}

客户端

public class Client {
    public static void main(String[] args) {
        //调用Factory的静态方法生成所要的类
        Factory.create("productA");
        Factory.create("ProductB");
    }
}

假如我们又要添加一个新的产品类C呢?

优点:能够根据外界给定的信息,决定应该创建哪个具体类对象。用户在使用时可以无需了解这些对象是如何创建的,有利于整个软件体系结构的优化。

缺点:违背面向对象设计的“开闭原则”和“单一职责原则”。因为我们每增加一个产品就要去修改工厂类的代码,而且一个工厂生产各式各样的产品显然职责不单一

2.工厂方法模式

定义:定义一个创建对象的接口(抽象工厂类),让其子类(具体工厂类)去决定实例化哪个类(具体产品类)。一个工厂实现一种产品,一对一的关系。

产品类中增加了ProductC


public class ProductC implements Product {
    public ProductC() {
        System.out.println("productC");
    }
}

声明工厂接口

public interface Factory {
    //声明产生产品类的方法
    public Product createProduct();
}

分别产生Product的Factory

public class FactoryA implements Factory {
    //实现工厂类的方法生成产品类A
    public Product createProduct()
    {
        return new ProductA();
    }

}

public class FactoryB implements Factory {
    //实现工厂类的方法生成产品类B
    public Product createProduct()
    {
        return new ProductB();
    }
}

public class FactoryC implements Factory {
    //实现工厂类的方法生成产品类C
    public Product createProduct()
    {
        return new ProductC();
    }
}


客户端

public class Client {
    public static void main(String[] args) {
        Factory factory;
        factory = new FactoryA();
        factory.createProduct();
        factory = new FactoryB();
        factory.createProduct();
        factory = new FactoryC();
        factory.createProduct();
    }
}

结论:工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现“开发-封闭”原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品类过多,我们就要生成很多的工厂类。假设现在需要针对每种产品生产对应的赠品,难道我们要新增一个Gift的生产工厂吗?其实没有必要,因为在这个场景下,每种产品必须附带了赠品,所以我们可以利用原有的工厂来生产赠品族。对于这种情况我们可以采用抽象工厂模式。

3.抽象工厂模式

定义:提供一个创建一系列相关或者相互依赖产品的接口,而无需制定他们的具体类,一对多的关系。抽象工厂模式是工厂方法模式的升级版

新增gift这个产品

public interface Gift {
    //声明产品赠品的接口,当然也可以是抽象类,同样为了简单就不声明方法了
}

public class GiftA implements Gift {
    public GiftA()
    {
        System.out.println("GiftA");
    }
}

public class GiftB implements Gift {
    public GiftB()
    {
        System.out.println("GiftB");
    }
}

Fatory

public interface Factory {
    public Product createProduct();
    public Gift createGift();

}

public class FactoryA implements Factory {
    @Override
    public Product createProduct()
    {
        return new ProductA();
    }
    @Override
    public Gift createGift()
    {
        return new GiftA();
    }
}

public class FactoryB implements Factory {
    @Override
    public Product createProduct() {
        return new ProductB();
    }
    @Override
    public Gift createGift() {
        return new GiftB();
    }

}

客户端

public class Client {
    public static void main(String[] args) {
        Factory factory;
        factory = new FactoryA();
        factory.createProduct();
        factory.createGift();
        factory = new FactoryB();
        factory.createProduct();
        factory.createGift();
    }
}

结论:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需制定他们具体的类。抽象工厂接口,应该包含所有的产品创建的抽象方法,我们可以定义实现不止一个接口,一个工厂也可以生产不止一种产品类,和工厂方法模式一样,抽象工厂模式同样实现了开发封闭原则

补充:需要注意的是学习最忌讳生搬硬套,为了设计模式而设计。设计模式主要解决的就是设计模式的六大原则,只要我们设计的代码遵循这六大原则,那么就是优秀代码。

另附设计模式六大原则

1、单一职责原则(Single Responsibility Principle)

定义 : 应该有且只有一个原因引起类的变化

注意 : 这里的类不光指类,也适用于方法和接口,比如我们常说的一个方法实现一个功能

2、里氏代换原则(Liskov Substitution Principle)

3、依赖倒置原则(Dependence Inversion Principle)

定义 : 依赖倒置原则包含三个含义
高层模块不应该依赖低层模块,两者都应该依赖其抽象
抽象不应该依赖细节
细节应该依赖抽象

4、接口隔离原则(Interface Segregation Principle)

5、迪米特法则(Demeter Principle)

定义 : 迪米特法则也叫最少知识原则,含义是 一个对象应该对其他对象有最少的了解,这个应该很好理解,就是降低各模块之间的耦合

6、开闭原则(Open Close Principle)

定义 : 一个软件实体如类,模块和函数应该对扩展开放,对修改关闭,开闭原则也是其他五个原则的基石

上一篇下一篇

猜你喜欢

热点阅读