设计模式之工厂模式,抽象工厂模式

工厂模式

先上代码:

//创建一个水果的接口
public interface Fruit {
   void eat();
}
//创建实现水果接口的苹果实体类
public class Apple implements Fruit {
 
   @Override
   public void eat() {
      System.out.println("eatApple");
   }
}
//创建实现水果接口的橘子实体类
public class Orange implements Fruit {
 
   @Override
   public void eat() {
      System.out.println("eatOrange");
   }
}
//创建实现水果接口的香蕉实体类
public class Banana implements Fruit {
 
   @Override
   public void eat() {
      System.out.println("eatBanana");
   }
}
//创建一个水果工厂,生成基于给定信息的实体类对象
public class FruitFactory {
    
   //使用 getFruit 方法获取形状类型的对象
   public Fruit getFruit(String fruitType){
      if(fruitType == null){
         return null;
      }        
      if(fruitType.equalsIgnoreCase("Apple")){
         return new Apple();
      } else if(fruitType.equalsIgnoreCase("Orange")){
         return new Orange();
      } else if(fruitType.equalsIgnoreCase("Banana")){
         return new Banana();
      }
      return null;
   }
}

//使用水果工厂,通过传递水果信息获取实体类的对象
public class FactoryFruitDemo {
 
   public static void main(String[] args) {
      FruitFactory fruitFactory = new FruitFactory();
 
      //获取 Apple 的对象,并调用它的 draw 方法
      Fruit fruit1 = fruitFactory.getFruit("Apple");
 
      //调用 Apple 的 draw 方法
      fruit1.eat();
 
      //获取 Orange 的对象,并调用它的 draw 方法
      Fruit fruit2 = fruitFactory.getFruit("Orange");
 
      //调用 Orange 的 draw 方法
      fruit2.eat();
 
      //获取 Banana 的对象,并调用它的 draw 方法
      Fruit fruit3 = fruitFactory.getFruit("Banana");
 
      //调用 Banana 的 draw 方法
      fruit3.eat();
   }
}

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

何时使用:我们明确地计划不同条件下创建不同实例时。

如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

 

抽象工厂模式

//创建一个水果的接口
public interface Fruit {
   void eat();
}
//创建实现水果接口的苹果实体类
public class Apple implements Fruit {
 
   @Override
   public void eat() {
      System.out.println("eatApple");
   }
}
//创建实现水果接口的橘子实体类
public class Orange implements Fruit {
 
   @Override
   public void eat() {
      System.out.println("eatOrange");
   }
}
//创建实现水果接口的香蕉实体类
public class Banana implements Fruit {
 
   @Override
   public void eat() {
      System.out.println("eatBanana");
   }
}

//创建一个动物的接口
public interface Animal {
   void say();
}
//创建实现动物接口的狮子实体类
public class Lion implements Animal {
 
   @Override
   public void say() {
      System.out.println("I'm Lion");
   }
}
//创建实现动物接口的狗实体类
public class Dog implements Animal {
 
   @Override
   public void say() {
      System.out.println("I'm Dog");
   }
}
//创建实现动物接口的猪实体类
public class Pig implements Animal {
 
   @Override
   public void say() {
      System.out.println("I'm Pig");
   }
}

//为Fruit和Animal对象创建抽象类来获取工厂
public abstract class AbstractFactory {
   public abstract Fruit getFruit(String fruit);
   public abstract Animal getAnimal(String animal);
}

//定义工厂继承查询工厂
public class MyFactory extends AbstractFactory {
	
   //使用 getFruit 方法获取形状类型的对象
   @Override
   public Fruit getFruit(String fruitType){
      if(fruitType == null){
         return null;
      }        
      if(fruitType.equalsIgnoreCase("Apple")){
         return new Apple();
      } else if(fruitType.equalsIgnoreCase("Orange")){
         return new Orange();
      } else if(fruitType.equalsIgnoreCase("Banana")){
         return new Banana();
      }
      return null;
   }

   //使用 getAnimal 方法获取形状类型的对象
   @Override
   public Animal getAnimal(String animalType){
      if(animalType == null){
         return null;
      }        
      if(animalType.equalsIgnoreCase("Lion")){
         return new Lion();
      } else if(animalType.equalsIgnoreCase("Dog")){
         return new Dog();
      } else if(animalType.equalsIgnoreCase("Pig")){
         return new Pig();
      }
      return null;
   }

}
//创建工厂创造器,通过传递种类获取不同的工厂
public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("Fruit")){
         return new MyFactory().getFruit();
      } else if(choice.equalsIgnoreCase("Animal")){
         return new MyFactory().getAnimal();
      }
      return null;
   }
}
//通过传递类型信息来获取实体类的对象
public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
    //获取形状工厂
    AbstractFactory shapeFactory = FactoryProducer.getFactory("Fruit");
 
    //获取形状为 apple 的对象
    Fruit fruit = shapeFactory.getShape("Apple");
    fruit.eat();
    //省略.....
   }
}

意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

主要解决:主要解决接口选择的问题。

何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

如何解决:在一个产品族里面,定义多个产品。

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

注意事项:产品族难扩展,产品等级易扩展。

 

抽象工厂跟工厂模式的区别

工厂模式: 只有一个抽象产品类,具体工厂类只能创建一个具体产品类的实例
抽象工厂模式: 有多个抽象产品类 ,具体工厂类能创建多个具体产品类的实例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值