设计模式——工厂模式

1.浅谈工厂模式的由来

一个对象的职责一般有三个:对象本身所具有的职责、创建对象的职责和使用对象的职责

对象本身所具有的职责就是对象内的方法

创建对象的职责一般有即指创建对象的方式

使用对象的责之是指关于对象的一些使用方法

public class Login {
    private UserDaO userdao;
    
    public login() {
        userdao = new JDBCUserDaO(); //创建对象
    }
    
    public void execute() {
        //业务逻辑
        userdao.findUserById(); //使用对象
        //业务逻辑
    }
}

上述的代码里,同时包含了创建对象和使用对象的职责。在这种情况下,如果UserDao还有一个子类CacheDao,login方法会根据不同的参数创建不同的类。这种情况下就需要改变Login这个类的方法,这就违背了开闭原则。

那么如何解决这个问题?

最常用的办法就是把UserDao的创建放在其他类里面,那个类专门负责对象的创建,至此工厂类就出现了。

即便以后还有其他UserDao的子类,只需要改变工厂类里面的代码即可实现,无需更改Login方法,这也符合单一职责的原则。

2. 简单工厂模式
2.1 创建Fruits接口
public interface Fruits {

    void appearance();
}

2.2 创建具体的实现类
public class Apple implements Fruits {
    @Override
    public void appearance() {
        System.out.println("我是绿色的苹果");
    }
}


public class Banana implements Fruits {
    @Override
    public void appearance() {
        System.out.println("我是金色的香蕉");
    }
}

public class Orange  implements Fruits {
    @Override
    public void appearance() {
        System.out.println("我是橙色的橘子");
    }
}
2.3 创建工厂类
public class FruitsFactory {


    public static Fruits getFruits(Integer type) {
	
        if (type == null) {
            return null;
        } else if (type.intValue() == 1) {
            return new Orange();
        } else if (type.intValue() == 2) {
            return new Banana();
        } else {
            return new Apple();
        }

    }
}
2.4 测试
public class test {

    public static void main(String[] args) {
        Fruits fruits = FruitsFactory.getFruits(1);
        fruits.appearance();

    }

}

至此一个简单的工厂模式就完成了。

但是这种模式下,如果新增一种type,则需要修改工厂类里的方法,这就违背了开闭原则,所以一般会用反射来升级代码

2.5 升级代码
public class FruitsFactory {


    public static Object getFruits(Class<? extends Fruits> clz){

        Object obj = null;
        try {
            obj = Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return obj;
    }
}
public class test {

    public static void main(String[] args) {
        Fruits fruits = (Fruits) FruitsFactory.getFruits(Orange.class);
        fruits.appearance();

    }

}

虽然解决了上述问题,但是使用者无法知道一个接口有多少可以使用的子类,从而也是一种弊端

3.工厂模式
3.1 创建工厂类接口
public interface FactoryInterface {

    Fruits getFruits();
}
3.2 创建工厂类
public class AppleFactory implements FactoryInterface{
    @Override
    public Fruits getFruits() {
        return new Apple();
    }
}


public class BananaFactory implements FactoryInterface{
    @Override
    public Fruits getFruits() {
        return new Banana();
    }
}

public class OrangeFactory implements FactoryInterface{
    @Override
    public Fruits getFruits() {
        return new Orange();
    }
}
3.3 测试
public class test {

    public static void main(String[] args) {
        FactoryInterface factory = new AppleFactory();
        Fruits fruits = factory.getFruits();
        fruits.appearance();
    }
}

工厂模式解决了简单工厂模式的弊端,每次新增一个种类,只要新增一个工厂类即可。假如FactoryInterface要实现的接口不止一个,则无法实现

4.抽象工厂模式

说明:抽象工厂是生产一整套有产品的(至少要生产两个产品),这些产品必须相互是有关系或有依赖的,而工厂方法中的工厂是生产单一产品的工厂。

4.1 工厂类接口
public interface Factory {

    Fruits getAppleFruits();

    Fruits getOrangeFruits();
}

这是一个只生产酸味道水果的工厂

4.2 工厂类
public class AcidFruits implements Factory{
    @Override
    public Fruits getAppleFruits() {
        return new Apple();
    }

    @Override
    public Fruits getOrangeFruits() {
        return new Orange();
    }
}
4.3 测试
public class test {

    public static void main(String[] args) {
        Factory factory = new AcidFruitsFactory();
        Fruits appleFruits = factory.getAppleFruits();
        Fruits orangeFruits = factory.getOrangeFruits();
        appleFruits.appearance();
        orangeFruits.appearance();
    }

}
5.框架里面出现的工厂模式

待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值