设计模式之禅之工厂方法模式

工厂方法模式的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类

样例:女娲通过八卦炉造白种人、黄种人、黑种人。

见代码:

//工厂要生产的人的接口
public interface Human{
//有两个方法
    public void getColor();
    public void talk();
}
//黑种人
public class BlackHuman implements Human {

    @Override
    public void getColor() {
        System.out.println("黑种人的皮肤是黑色的");

    }

    @Override
    public void talk() {
        System.out.println("黑人会说话,一般人都听不懂");
    }

}
//黑种人
public class YellowHuman implements Human {

    @Override
    public void getColor() {
        System.out.println("黄种人的皮肤是黄色的");

    }

    @Override
    public void talk() {
        System.out.println("黄种人会说话,一般人说的都是双字节");

    }

}
//白种人
public class WhiteHuman implements Human {

    @Override
    public void getColor() {
        System.out.println("白种人的皮肤是白色的");

    }

    @Override
    public void talk() {
        System.out.println("白种人人会说话,一般说的都是单子节");

    }

}

下面的代码用到了泛型

//抽象人类创建工厂,泛型限定了输入参数必须是Class类型、必须是Human的实现类
public abstract class AbstractHumanFactory {
    public abstract <T extends Human> T creatHuman(Class<T> c);
}
//人类创建工厂
public class HumanFactory extends AbstractHumanFactory {

    @Override
    public <T extends Human> T creatHuman(Class<T> c) {
        // TODO Auto-generated method stub
        Human human = null;
        try{
            human = (Human)Class.forName(c.getName()).newInstance();
        }catch(Exception e){
            System.out.println("人类生产错误");
            e.printStackTrace();
        }
        return (T)human;
    }

}

ok,现在让我们想一下女娲会给八卦炉下达什么样的生产命令呢?应该是“给我生产一个黄色人种”,而不会是“给我生产一个会走、会跑、会说话、皮肤是黄色的人”,因为这样的命令增加了交流的成本,作为一个生产的管理者,只要知道生产什么就可以了,而不需要失误的具体信息。

现在女娲开始干活了

下面的代码用到了反射机制。我写的反射机制的blog被我删了…不过这个代码挺简单的,可以理解。这里的反射机制也是反射的非常重要的应用。


public class NvWa {

    public static void main(String[] args) {
        AbstractHumanFactory YinYanglu = new HumanFactory();
        System.out.println("--造出的第一批人是白色人种");
        Human whiteHuman = YinYanglu.createHuman(WhiteHuman.class);
        whiteHuman.getColor();
        whiteHuman.talk();
        System.out.println("--造出的第二批人是黑色人种");
        Human blackHuman = YinYanglu.createHuman(BlackHuman.class);
        blackHuman.getColor();
        blackHuman.talk();
        System.out.println("--造出的第一批人是黄色人种");
        Human yellowHuman = YinYanglu.createHuman(YellowHuman.class);
        yellowHuman.getColor();
        yellowHuman.talk();
    }
}

怎么样,是不是辣么灰常简单~

下面是工厂模式的一个比较实用、易拓展的框架,读者可以根据实际项目需要进行拓展

//抽象产品类
public abstract class Product{
    public void method1(){
        //业务逻辑处理
    }
    //抽象方法
    public abstract void method2();

}
//具体的产品类
public class ConcreteProduct01 extends Product{
    public void method2(){
        //业务逻辑处理
    }
}
----------
public class ConcreteProduct02 extends Product{
    public void method2(){
        //业务逻辑处理
    }
}
//抽象工厂类
public abstract class Creator{
    /*
    *创建一个产品对象,其输入参数类型可以自行设置
    *通常为String、Enum、Class等,当然也可以为空
    /*
    //输入参数类型是Class,用的反射机制
    public abstract <T extends Product> T createProduct(Class<T> c);
    /*
    *为了让大家知道为什么用反射机制,这里添加一种输入类型是String的比较一下
    pubic abstract <T extends Product> T creatProduct(String productname);
    */

}
//具体工厂类
public class ContreteCreator extends Creator{
    public <T extends Product> T createProduct(Class<T> c){
        Product product = null;
        try{
            product = (Product)Class.forName(c.getName()).newInstance();
        }catch(Exception e){
            System.out.println("产品创造失败了");
            e.printStackTrance();
        }
    }
    /*public <T extends Product> T createProduct(String productname){
            Product product = null;
            try{
            //反射机制可以避免这些繁琐的判断。并且如果这么写,一点你有了新的产品类,还需要来修改代码,差评~
            if(productname == "productname01") product = new ConcreteProduct01();
            else if(productname == "productname02")product = new ConcreteProduct02();
        }catch(Exception e){
            System.out.println("产品创造失败了");
            e.printStackTrance();
        }
    }
    */
}
//场景类
public class Client{
    public static void main(String[] args){
        Creator creator = new ConcreteCreator();
        Product product = creator.createProduct(ConcreteProduct1.class);
    }
}

工厂方法模式的基本代码就是这些,下面让我们来看一下它的优点

1、首先,良好的封装性,代码结构清晰。一个调用者需要一个具体的产品对象的话,只要知道这个产品的类名(或你使用的字符串)就可以了。

2、工厂方法模式的封装性非常优秀。在增加产品类的情况下,只要适当地修改具体的工厂类(用反射机制是不用修改的)或拓展一个工厂类,就可以完成“拥抱变化”。

3、屏蔽产品类。产品类如何变化,只要产品接口不变就跟我们没有关系。

4、最后,工厂模式方法是典型的解耦框架。高层模块只需要知道产品的抽象类,别的不用关心,符合迪米特法则。只依赖产品类的抽象,符合依赖倒置原则。使用产品子类替换产品父类,也符合里氏替换原则

还没有结束!

厂方法模式的拓展

1、缩小为简单工厂模式。如果只有一种工厂,那么我们就不需要抽象工厂了,产品类都不需要改变,同时这个唯一工厂的方法设置成static的

public class HumanFactory{
    //这里是
    public static <T extends Human> T createHuman(Class<T> c){
    Human human = null;
        try{
            human = (Human)Class.forName(c.getName()).newInstance();
        }catch(Exception e){
            System.out.println("人类生产错误");
            e.printStackTrace();
        }
        return (T)human;
}

}

2、升级为多个工厂类

当我们在做一个比较复杂的项目时,经常会遇到初始化一个对象很耗费精力的情况,所有的产品类都放到一个工厂方法中进行初始化,会是代码结构不清晰。例如,如果一个产品类有5个具体实现,每个实现类的初始化(不仅仅是new,还包括对对象设置初始值等)都不相同,如果写在一个工厂方法中,势必会导致该方法类巨大无比。

怎么办呢?

每一种产品都有自己的工厂,并在自己的工厂中初始化自己。意思比较简单,就不再添加代码了,自己尝试一下吧~

时间: 2024-10-16 09:17:08

设计模式之禅之工厂方法模式的相关文章

设计模式(二)---工厂方法模式

设计模式(二)---工厂方法模式 工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品. 抽象工厂源代码 public interface Creator { /** * 工厂方法 */ public Product factory(); } 抽象产品

设计模式(二)——工厂方法模式

设计模式(二)--工厂方法模式 一.工厂方法模式简介 1.工厂方法模式简介 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法将一个类的实例化延迟到其子类. 对每一个子类产品都分别对应一个工厂子类,用来创建相应的产品,若增加了新的产品,只需相应增加工厂子类即可. 工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得工厂方法可以被子类继承. 工厂方法模式特点: (1)工厂方法模式是对简单工厂模式的稍微的改进.工厂方法模式的用意是定义一个

设计模式C#实现(八)——工厂方法模式和简单工厂

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. 构成: 1.Product工厂方法创建的对象的接口 2.ConcreteProduct具体的产品,实现Product接口 3.Creator声明工厂方法,返回Product 4.ConcreteCreator实现/重写Creator的工厂方法,返回ConcreteProduct实例 UML类图: 实现 要生产的产品都实现一个接口 interface Product {

从王者荣耀看设计模式(十四.工厂方法模式)

从王者荣耀看设计模式(工厂方法模式) 二.简介 王者荣耀游戏设计师根据英雄技能.属性.天赋等因素,将英雄划分为射手.辅助.打野.法师.坦克.战士等职业.一局比赛存在多类英雄可供选择.玩家在挑选游戏英雄时,合理的英雄职业搭配是赢得游戏胜利的基本保证. 三.工厂方法模式 工厂方法模式(Factory Method Pattern):工厂方法模式又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式.在

Java设计模式菜鸟系列(四)工厂方法模式建模与实现

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39760895 工厂方法模式(Factory Method) 工厂方法:顾名思义,就是调用工厂里的方法来生产对象(产品)的. 工厂方法实现方式有3种: 一.普通工厂模式.就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建. 1.uml建模图: 2.代码实现 /** * 示例(一):普通工厂方法 * * 缺点:如果传递的字符串出错,则不能正确创建对象 */ interface Sen

设计模式(4)---工厂方法模式

1.简单工厂模式(simple factory)    简单工厂模式属于创建型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 1 package SimpleFactory; 2 3 public abstract class Animal { 4 5 public abstract void eat(); 6 7 } 1 package SimpleFactory; 2 3

设计模式之二:工厂方法模式

工厂方法模式(Factory Method): 定义:Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses(定义一个用于创建对象的接口,让子类决定实例化哪一个类. 工厂方法使一个类的实例化延迟到其子类). 在工厂方法模式中,抽象类Pr

设计模式笔记6:工厂方法模式

1.1 定义 简单工厂增加计算功能需要增加case语句修改工厂类.违背了开放封闭原则. 工厂方法模式:定义一个创建对象的接口,让子类决定实例化哪一个类. 1.2 类图 工厂模式:抽象出一个工厂父类,每一个功能做为一个子工厂.这时候要增加一个计算功能,要在计算类增加一个功能类,并且增加对应的工厂类.这样避免了改变工厂类,而是通过扩展的方法来新增功能.

设计模式那点事--工厂方法模式

概念: 工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 组成角色: 在简单工厂模式中,我们把动态创建具体产品类对象放在工厂类.由于它负责具体产品对象的分支判断,容易产生高耦合.根据依赖倒转原则,我们在此基础上,把工厂类抽象为一个接口,然后让具体工厂去实现该接口方法.组成角色为: 抽象工厂,具体工厂,抽象产品,具体产品. 例子: 一个鲜活简单的例子总能让人轻松地理解晦涩的概念.我们来看看一个关于汽车价格的工厂方法模式. 我们知道,汽车的品