学习笔记:设计模式之工厂模式

本文仅供学习交流使用,侵权必删。
不作商业用途,转载请注明出处。

WHAT 什么是工厂

工厂模式是一种创建型的设计模式。工厂模式细分的话会被分为简单工厂、工厂方法和抽象工厂这三类。
我的理解工厂模式就是将子类的实例化逻辑交给一个工厂类执行。工厂类利用了面向对象多态和封装的特性,将创建对象的逻辑封装在一个工厂类中,然后利用多态的特性,根据条件判断创建具体的子类的实例。

简单工厂

简单工厂.png

简单工厂,子类创建逻辑都封装到一个工厂类的创建方法中,简单明了。但是如果子类对象过多,存在大量逻辑判断,并将所有的创建逻辑都写在一个方法中,可读性比较差。此外,添加子类就需要改动原来创建逻辑代码,违反开闭原则,而且创建逻辑代码会随着子类的添加而不断膨胀。

工厂方法

工厂方法.png

工厂方法,每个子类的创建都对应一个工厂类。如果创建实例逻辑复杂,能够较好将所有创建逻辑分开,提高可读性,工厂类职责更加单一,并且符合开闭原则。但如果每添加一个子类都要添加一个对应的工厂类,那么就会造成类个数过多。此外,工厂类的创建会耦合到调用函数中,这个问题我们可以通过一个工厂容器解决,将工厂放到工厂容器我们直接使用即可。

抽象工厂

抽象工厂.png

抽象工厂,为一类系列的产品创建对象。每个实际工厂创建实际一系列的产品对象,工厂类是基于产品系列区分开的。这样能有效减少工厂类的个数。但依然违反了开闭原则,每次添加一个产品,那么每个对应的实际工厂都需要做修改。
不过应对这种情况我们可以使用反射和配置文件的方式,创建的对象我们可以添加到配置文件。创建过程交给框架,既符合开闭原则又符合依赖倒置原则

WHY 为什么使用工厂

  1. 这种模式能降低了客户端与产品类的耦合度,客户端创建一个产品实例只需要通过调用工厂类的创建方法即可。如果对象实例化逻辑。
  2. 将创建逻辑封装到工厂类中,对调用者透明,调用者无需关注复杂的对象创建逻辑,并且能让原来的方法职责更单一,代码更简洁,提高了代码的可读性。
  3. 将创建对象代码逻辑统一封装在工厂类中,提高了代码的复用性

HOW 工厂的实现(JAVA)

简单工厂

举例背景:通过简单工厂创建不同类型的配置文件解析器

  • 解析器类
/**
 * 解析器接口类
 */
public interface IConfigParser {
    void parse();
}


/**
 * 解析器类型
 */
public enum ParserType {
    JSON,
    XML,
    YAML;
}


/**
 * json配置文件解析器
 */
public class JsonConfigParser implements IConfigParser {
    @Override
    public void parse() {
        System.out.println("json");
    }
}


/**
 * xml配置文件解析器
 */
public class XmlConfigParser implements IConfigParser {
    @Override
    public void parse() {
        System.out.println("xml");
    }
}


/**
 * yaml配置文件解析器
 */
public class YamlConfigParser implements IConfigParser {
    @Override
    public void parse() {
        System.out.println("yaml");
    }
}
  • 简单工厂类
public class SimpleFactory {

    public static IConfigParser createParser(ParserType type) {
         
        if (type == null) {
            return null;
        }

        if (type == ParserType.JSON) {
            return new JsonConfigParser();
        } else if (type == ParserType.YAML) {
            return new YamlConfigParser();
        } else if (type == ParserType.XML) {
            return new XmlConfigParser();
        } else {
            throw new IllegalArgumentException("");
        }
    }
}

工厂方法

举例背景:举例背景:通过工厂方法创建不同类型的配置文件解析器

  • 解析器类同简单工厂一样

  • 工厂类

/**
 * 工厂类接口
 */
public interface IFactory {

    IConfigParser createParser();
}


/**
 * Json解析器工厂
 */
public class JsonConfigParserFactory implements IFactory {
    @Override
    public IConfigParser createParser() {
        return new JsonConfigParser();
    }
}


/**
 * Xml解析器工厂
 */
public class XmlConfigParserFactory implements IFactory {
    @Override
    public IConfigParser createParser() {
        return new XmlConfigParser();
    }
}


/**
 * Yaml解析器工厂
 */
public class YamlConfigParserFactory implements IFactory {
    @Override
    public IConfigParser createParser() {
        return new YamlConfigParser();
    }
}

抽象工厂

举例背景:根据不同的数据库类型,创建不同的对象。因为不同的数据库,有可能对数据库操作也是不一样的。我们将对数据库的操作封装在对应的对象中,那么每次根据数据库类型创建对应的对象

  • 对象接口类
public interface IUser {

    long insert(IUser user);

    IUser getUser(String id);
}


public interface IDepartment {

    long insert(IDepartment department);

    IDepartment getDepartment(String id);
}

  • 对象实现类


public class SqlServerUser implements IUser {
    @Override
    public long insert(IUser user) {
        System.out.println("sqlserver user insert");
        return 1;
    }

    @Override
    public IUser getUser(String id) {
        return new SqlServerUser();
    }
}


public class SqlServerDepartment implements IDepartment {
    @Override
    public long insert(IDepartment department) {
        System.out.println("sqlserver department insert");
        return 1L;
    }

    @Override
    public IDepartment getDepartment(String id) {
        return new SqlServerDepartment();
    }
}


public class MysqlUser implements IUser {
    @Override
    public long insert(IUser user) {
        System.out.println("mysql user insert");
        return 1L;
    }

    @Override
    public IUser getUser(String id) {
        return new MysqlUser();
    }
}


public class MysqlDepartment implements IDepartment {
    @Override
    public long insert(IDepartment department) {
        System.out.println("mysql department insert");
        return 1L;
    }

    @Override
    public IDepartment getDepartment(String id) {
        return new MysqlDepartment();
    }
}
  • 工厂类
/**
 * 抽象工厂类
 */
public abstract class AbstractFactory {

    public abstract IUser createUser();

    public abstract IDepartment createDepartment();
}


/**
 * Mysql工厂类
 */
public class MysqlFactory extends AbstractFactory {
    @Override
    public IUser createUser() {
        return new MysqlUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new MysqlDepartment();
    }
}


/**
 * SqlServer工厂类
 */
public class SqlServerFactory extends AbstractFactory {
    @Override
    public IUser createUser() {
        return new SqlServerUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new SqlServerDepartment();
    }
}

持续更新...

你可能感兴趣的:(学习笔记:设计模式之工厂模式)