设计模式入门:工厂方法模式

原文地址:http://te-amo.site/user/article/info/ARTICLE20180411032005619
文章中部分定义和解释性文字,都是引用百度百科,主要的代码及场景应用为本人原创

工厂方法模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的

场景:在简单工厂的场景上,有了新的需求:创建管理员用户时,需要指定ID:0~100,名字为:admin,有效时长:10分钟;创建一般用户时,需要指定ID:100~200,名字为:与ID相同,有效时长:5分钟;创建匿名用户时,需要指定ID:200~300,名字为:anonymous,有效时长:1分钟 。用户实例化完成后要激活用户。

设计

这里写图片描述

结构

  • 抽象工厂(Creator)角色:任何在模式中创建的对象的工厂类必须实现这个接口。(UserFactory)
  • 具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。(AdminUserFactory,AnonymousUserFactory,NormalUserFactory)
  • 抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。(User)
  • 具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建。(AdminUser,AnonymousUser,NormalUser)

实现

代码地址:https://github.com/telundusiji/designpattern

抽象产品 抽象用户

@Data
public abstract class User {
    private int id;
    private String name;
    private String role;
    private long active;
    private boolean status;

    public abstract void init(int id,String name,long active);
}

具体产品 管理员用户

public class AdminUser extends User {

    @Override
    public void init(int id, String name, long active) {
        setId(id);
        setName(name);
        setRole("管理员");
        setActive(active);
    }
}

具体产品 匿名用户

public class AnonymousUser extends User {

    @Override
    public void init(int id, String name, long active) {
        setId(id);
        setName(name);
        setRole("匿名用户");
        setActive(active);
    }
}

具体产品 一般用户

public class NormalUser extends User {

    @Override
    public void init(int id, String name, long active) {
        setId(id);
        setName(name);
        setRole("一般用户");
        setActive(active);
    }
}

抽象工厂

@Slf4j
public abstract class UserFactory {
    public abstract User createUser();
    public void userActive(User user){
        user.setStatus(true);
        log.info("{}激活成功!",user.toString());
    }
}

具体工厂 管理员工厂

public class AdminUserFactory extends UserFactory {
    @Override
    public User createUser() {
        AdminUser adminUser = new AdminUser();
        adminUser.init((int)(Math.random()*100),"admin",1000*60*10);
        userActive(adminUser);
        return adminUser;
    }
}

具体工厂 匿名用户工厂

public class AnonymousUserFactory extends UserFactory{
    @Override
    public User createUser() {
        AnonymousUser anonymousUser = new AnonymousUser();
        anonymousUser.init((int)(Math.random()*100+200),"anonymous",1000*60*1);
        userActive(anonymousUser);
        return anonymousUser;
    }
}

具体工厂 一般用户工厂

public class NormalUserFactory extends UserFactory {
    @Override
    public User createUser() {
        NormalUser normalUser = new NormalUser();
        int id = (int)(Math.random()*100+100);
        normalUser.init(id,String.valueOf(id),1000*60*5);
        userActive(normalUser);
        return normalUser;
    }
}

经典应用

java.net.URLStreamHandlerFactory 是一个工厂方法的典型应用:

  • 抽象工厂:java.net.URLStreamHandlerFactory
  • 具体工厂:实现URLStreamHandlerFactory 接口的类
  • 抽象产品:java.net.URLStreamHandler
  • 具体产品:继承URLStreamHandler抽象类并实现其抽象方法的类

总结

  • 工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,仅负责具体工厂子类必须实现的接口,可以使系统在不修改具体工厂角色的情况下引进新的产品。
  • 工厂方法模式是简单工厂模式的衍生,实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章