设计模式——工厂模式

在面向对象编程中,由于有继承blackDog可以当成Dog处理,如果要扩展新的Dog,只需要添加新的类就好了,因此关键时如何创建一个对象。通常我们使用(Dog dog = new BlackDod();)创建一个对象,当我们需要创建一个新的对象时,就需要更改代码,这样就违背了开闭原则,其次主类除了其固有的功能外,还需要负责创建新的对象,这也违背了单一原则,因此可以增加新的类用于创建对象,称之为工厂模式。

简单工厂模式

静态工厂模式
在Factory类中用枚举列举了所要创建的所有对象的名称,当要创建一个对象时,使用Factory中的静态方法create创建。
public class Factory {
    public enum DogType{
        BlackDog,WhiteDog,BlueDog;
    }
    public static Dog create(DogType type){
        if(type.equals(DogType.WhiteDog))
            return new WhiteDog;
        if(type.equals(DogType.BlackDog))
            return new BlackDog;
        if(type.equals(DogType.BlueDog))
            return new BlueDog;
        else return null;
    }
}
使用反射机制进行类注册的简单工厂模式
静态工厂模式中,当我们需要增加一个新的类时,需要修改Factory类,这违背了开闭原则。因此可以增加注册类对象和实例化类对象的方法,使用map对象来保存ID及其对应的类。但反射机制需要运行时权限,也会降低效率,可以在Dog基类中添加抽象方法newInstance();实现。
public class Factory {
    private Map<String,Class> registeredDog = new HashMap<String, Class>();
    
    public void registerDog(String dogId, Class dogClass){
        registeredDog.put(dogId,dogClass);
    }
    public Dog create(String type) throws IllegalAccessException, InstantiationException {
        Class dogClass = registeredDog.get(type);
        return (Dog)dogClass.newInstance();
    }
}
使用newInstance方法进行类注册的简单工厂模式
在Dog基类中添加一个抽象方法
abstract public Dog newInstance();
对每一个具体的Dog,都要实现基类声明的抽象方法。
@Override
public BlackDog newInstance(){
	return new BlackDog();
}
public class Factory {
    private Map<String,Dog> registeredDog = new HashMap<String, Dog>();

    public void registerDog(String dogId, Dog dog){
        registeredDog.put(dogId,dog);
    }
    public AbstractDog create(String type){
        return registeredDog.get(type).newInstance();
    }
}

工厂方法模式

工厂方法模式是在静态工厂模式上的改进,工厂类被抽象化,实例化具体产品的代码写在实现抽象方法的子类中,这样扩展工厂类就可以避免修改代码了。
我们来看一个例子:假设有一个宠物店,里面有品种和颜色不同的猫,顾客可以自由决定购买什么类型的猫。我们先创建一个Cat类和两个子类,子类为RagdollCat和ManxCat.
创建抽象工厂类,抽象工厂类中不包含任何创建实例的代码。
public abstract class AbstractFactory {
    protected abstract Cat createCat(String breed);
    public Cat orderCat(String breed, String color){
        Cat cat = createCat(breed);
        cat.setColor(color);
        return cat;
    }
}
我们创建了AbstractFactory的子类CatFactory类,实现了实例化猫的代码。
public class CatFactory extends AbstractFactory{
    @Override
    protected Cat createCat(String breed) {
        if(breed.equals("ragdoll"))
            return new RagdollCat();
        else if(breed.equals("manx"))
            return new ManxCat();
        return null;
    }
}
在客户端,我们只需创建工厂类,获取猫。
AbstractFactory catFactory = new CatFactory();
catFactory.orderCat("manx","white");

抽象工厂模式

抽象工厂模式是工厂方法模式的扩展,围绕一个超级工厂创建其他工厂,它创建一系列相关联的对象,该超级工厂又称为其他工厂的工厂。
还以上面的宠物店为例,里面不仅有品种不同的猫,还有品种不同的狗,顾客可以自由决定购买什么类型的猫和狗。我们先创建一个Cat类和两个子类,子类为RagdollCat和ManxCat,然后再创建一个Dog类和两个子类,子类为HuskyDog和PoodleDog。
为 Cat和 Dog 对象创建抽象类来获取工厂
public abstract class AbstractFactory {
    public abstract Dog getDog(String breed);
    public abstract Cat getCat(String breed) ;
}
创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象。
public class DogFactory extends AbstractFactory {
    @Override
    public Dog getDog(String breed){
        if(breed == null)
            return null;
        if(breed.equalsIgnoreCase("husky"))
            return new HuskyDog();
        else if(breed.equalsIgnoreCase("poodle"))
            return new PoodleDog();
        return null;
    }
    @Override
    public Cat getCat(String breed) {
        return null;
    }
}
public class CatFactory extends AbstractFactory {
    @Override
    public Dog getDog(String breed){
        return null;
    }
    @Override
    public Cat getCat(String breed) {
        if(breed == null)
            return null;
        if(breed.equalsIgnoreCase("ragdoll"))
            return new RagdollCat();
        else if(breed.equalsIgnoreCase("manx"))
            return new ManxCat();
        return null;
    }
}
创建一个工厂生成器类,通过传递cat或dog信息来获取工厂。
public class FactoryProducer {
    public static AbstractFactory getFactory(String choice){
        if(choice.equalsIgnoreCase("cat")){
            return new CatFactory();
        } else if(choice.equalsIgnoreCase("dog")){
            return new DogFactory();
        }
        return null;
    }
}
在客户端,我们先获取具体的工厂类对象,再通过工厂类对象获取猫或狗。
//获取Cat工厂
AbstractFactory catFactory = FactoryProducer.getFactory("cat");
//获取ragdollCat
Cat ragdollCat = catFactory.getCat("ragdoll");
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值