工厂模式的应用场景:
1.创建复杂对象,这个对象需要很多参数,大多数参数是固定的
2.构建同产品的不同对象
简单工厂模式:
定义季节接口,春夏秋冬四个季节实现这个接口,并对自己的季节进行描述
package sdibt.lxj.entity;
public interface Season {
public void desc();
}
春天
package sdibt.lxj.entity;
public class Spring implements Season{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("春天到了---");
}
}
夏天
package sdibt.lxj.entity;
public class Summer implements Season{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("夏天到了---");
}
}
秋天
package sdibt.lxj.entity;
public class Summer implements Season{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("夏天到了---");
}
}
冬天
package sdibt.lxj.entity;
public class Winter implements Season{
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("冬天到了---");
}
}
现在我要获取一个季节,但是我不自己创建了,需要在一个工厂里面拿,就定义一个季节工厂,让工厂给产生对象
package sdibt.lxj.factorypattern;
import sdibt.lxj.entity.Autumn;
import sdibt.lxj.entity.Season;
import sdibt.lxj.entity.Spring;
import sdibt.lxj.entity.Summer;
import sdibt.lxj.entity.Winter;
public class SimpleFactory {
public static Season getSeason(String seasonName){
if(seasonName.equals("spring")){
return new Spring();
}else if(seasonName.equals("summer")){
return new Summer();
}else if(seasonName.equals("autumn")){
return new Autumn();
}else if(seasonName.equals("winter")){
return new Winter();
}else{
return null;
}
}
}
测试一下
package sdibt.lxj.test;
import sdibt.lxj.entity.Season;
import sdibt.lxj.factorypattern.SimpleFactory;
public class Demo1 {
public static void main(String[] args) {
Season season = SimpleFactory.getSeason("autumn");
season.desc();
}
}
秋天到了---
这种设计模式的优点的是创建对象的过程不用分布在项目的各个部分,这个流程就交给了一个工厂,这个类现在比较简单,但是如果创建一个类需要很复杂的流程,这种设计模式的优点就体现出来了,便于管理创建对象。
当然这种设计模式也有缺点,就是扩展性差。当我需要在工厂中添加一个新产品时,就要修改工厂类。违背了ocp原则,所以有了工厂方法模式
工厂方法模式:
四个核心角色:抽象工厂,具体工厂,抽象产品,具体产品
抽象工厂类
package sdibt.lxj.entity;
public interface AbstractAnimalFactory {
/**
* 创建一个Animal
* @return
*/
public Animal createAnimal();
}
具体工厂
dog工厂:
package sdibt.lxj.entity;
/**
* 具体的Dog工厂,具体用来生成狗
* @author lxj
*
*/
public class DogFactory implements AbstractAnimalFactory{
@Override
public Animal createAnimal() {
// TODO Auto-generated method stub
return new Dog();
}
}
cat工厂
package sdibt.lxj.entity;
/**
* 具体的Cat工厂,具体用来生成猫
* @author lxj
*
*/
public class CatFactory implements AbstractAnimalFactory{
@Override
public Animal createAnimal() {
// TODO Auto-generated method stub
return new Cat();
}
}
抽象产品
Animal
package sdibt.lxj.entity;
/**
* 抽象动物类,其他的动物是继承该类
* @author lxj
*
*/
public abstract class Animal {
public abstract void call();
}
具体产品
package sdibt.lxj.entity;
/**
* Dog类
* @author lxj
*
*/
public class Dog extends Animal{
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("汪汪汪------");
}
}
package sdibt.lxj.entity;
/**
* Cat工厂
* @author lxj
*
*/
public class Cat extends Animal{
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("喵喵喵------");
}
}
测试
package sdibt.lxj.test;
import sdibt.lxj.entity.Animal;
import sdibt.lxj.entity.DogFactory;
/**
* 测试工厂方法
* @author lxj
*
*/
public class Demo2 {
public static void main(String[] args) {
//创建狗工厂
DogFactory df = new DogFactory();
Animal dog = df.createAnimal();
dog.call();
}
}
汪汪汪------
如果需要增加一个新的产品,只需要创建一个新的产品继承抽象产品,再创建一个该产品的具体产品工厂实现抽象产品接口。。。确实比简单工厂复杂,不过却很好的解决了ocp问题。只需要增加需要的类,而不需要修改已有的类。
不过缺点也明显,每增加一个具体产品就增加一个具体工厂