欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

工厂方法模式及在Android源码中的应用

程序员文章站 2022-05-21 16:20:54
工厂方法 在任何需要生成复杂对象的地方,都可以使用工厂方法模式,复杂对象适合使用工厂方法模式,用 new 就可以完成创建的对象无需使用工厂方法模式。 优点:降低了对象之间的耦合...

工厂方法

在任何需要生成复杂对象的地方,都可以使用工厂方法模式,复杂对象适合使用工厂方法模式,用 new 就可以完成创建的对象无需使用工厂方法模式。

优点:降低了对象之间的耦合度,工厂模式依赖于抽象的架构,其将实例化的任务交由子类去完成,有非常好的扩展性。
缺点:每次为工厂方法添加新的产品时就要编写一个新的产品类,同还要引入抽象层,必然会导致代码类结构的复杂化。

工厂方法模式的通用模式代码如下:
1. 抽象工厂方法(核心),具体生产什么由子类去实现:

public abstract class factory {
    public abstract product createproduct();
}
具体工厂类(实现了具体业务逻辑):
public class concretefactory extends factory{
    @override
    public product createproduct() {
        return new concreteproducta(); // 返回具体的产品对象
        //return new concreteproductb(); // 返回具体的产品对象
    }
}
抽象产品类,由具体的产品类去实现:
public abstract class product {
    public abstract void method();
}
具体产品类(包含concreteproducta、concreteproductb等):
public class concreteproducta extends product {
    @override
    public void method() {
        system.out.println("concreteproducta method");
    }
}
public class concreteproductb extends product {
    @override
    public void method() {
        system.out.println("concreteproductb method");
    }
}
测试程序:
@test
public void factorytest() throws exception {
    factory factory = new concretefactory();
    product product = factory.createproduct();
    product.method();
}

输出:concreteproducta method

这种方式比较常见,需要哪个就生产哪个,有时候还可以利用反射的方式更加简洁地来生产具体产品对象,此时,需要在工厂方法的参数列表中传入一个 class 类来决定是哪一个产品类:

public abstract class factory {
    /**
     * @param clz 产品对象类类型
     * @param  具体的产品对象
     * @return
     */
    public abstract  t createproduct(class clz);
}

对应的具体工厂类则通过反射获取类的实例即可:

public class concretefactory extends factory{
    @override
    public  t createproduct(class clz) {
        product p = null;
        try {
            p = (product) class.forname(clz.getname()).newinstance();
        } catch (exception e) {
            e.printstacktrace();
        }
        return (t) p;
    }
}

再看一下测试代码的实现:

@test
public void factorytest() throws exception {
    factory factory = new concretefactory();
    product product = factory.createproduct(concreteproducta.class);
    product.method();
    product product = factory.createproduct(concreteproducta.class);
    product.method();
}

输出:
concreteproducta method
concreteproductb method

需要哪个类的对象传入哪一个类即可,这种方法比较简洁、动态。如果不喜欢这一种,也可以尝试为每一个产品都定义一个具体的工厂,各司其职,像拥有多个工厂的方式我们称为多工厂方法模式,同样当我们的工厂类只有一个的时候,我们还可以简化掉抽象类,只需要将对应的工厂方法给为静态方法即可:

public class factory {
    public static product createproduct() {
        return new concreteproducta();
    }
}

工厂方法模式应用很广泛,开发中使用到的数据结构中就隐藏着对工厂方法模式的应用,例如 list、set,list、set 继承自 collection 接口,而 collection 接口继承于 iterable 接口:

public interface iterable {
    iterator iterator();
}

这意味着 list、set 接口也会继承 iterator() 方法,下面以 arraylist 为例进行分析:
arraylist 中 iterator() 方法的实现就是构造并返回一个迭代器对象:

public class arraylist extends abstractlist
        implements list, randomaccess, cloneable, java.io.serializable {
    public iterator iterator() {
        return new itr();
    }
    // 迭代器
    private class itr implements iterator {
        protected int limit = java.util.arraylist.this.size;
        int cursor;       // index of next element to return
        int lastret = -1; // index of last element returned; -1 if no such
        int expectedmodcount = modcount;

        public boolean hasnext() {
            return cursor < limit;
        }
        @suppresswarnings("unchecked")
        public e next() {
            if (modcount != expectedmodcount)
                throw new concurrentmodificationexception();
            int i = cursor;
            if (i >= limit)
                throw new nosuchelementexception();
            object[] elementdata = java.util.arraylist.this.elementdata;
            if (i >= elementdata.length)
                throw new concurrentmodificationexception();
            cursor = i + 1;
            return (e) elementdata[lastret = i];
        }
        public void remove() {
            if (lastret < 0)
                throw new illegalstateexception();
            if (modcount != expectedmodcount)
                throw new concurrentmodificationexception();
            try {
                java.util.arraylist.this.remove(lastret);
                cursor = lastret;
                lastret = -1;
                expectedmodcount = modcount;
                limit--;
            } catch (indexoutofboundsexception ex) {
                throw new concurrentmodificationexception();
            }
        }
        // 代码省略
    }
    // 代码省略
}

其中的 iterator() 方法其实就相当于一个工厂方法,专为 new 对象而生,构造并返回一个具体的迭代器。

其实android中对工厂方法模式的应用更多,先看如下代码:

public class aactivity extends activity{
    @override
    protected void oncreate(bundle savedinstancestate){
        super.oncreate(savedinstancestate);
        setcontentview(new linearlayout(this));
    }
}

实际上,oncreate方法就相当于一个工厂方法,因为linearlayout是一个viewgroup,而viewgroup又继承于view,简单地说,所有控件都是view的子类。在aactivity的oncreate方法中构造一个view对象,并设置为当前的contentview返回给framework处理,如果现在又有一个bactivity,这时又在oncreate方法中通过setcontentview方法设置另外不同的view,这是不是一个工厂模式的结构呢,其实设计模式离我们非常近!!!