设计模式之~简单工厂,工厂模式,抽象工厂~man看了会沉默

工厂模式


简单工厂

定义:

​ 由一个工厂对象决定创建出哪一种产品类的实例。

类型:

​ 创建型,但不属于GOF23种设计模式。

适用场景:

​ 工厂类负责创建的对象比较少。

​ 客户端(应用层)只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心。

优点:

​ 只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

缺点:

​ 工厂类的职责相对过澡,增加新的产品需要修改工厂类的判断逻辑,违背开闭原则。同时增加了系统类的个数。无法形成基于继承的等级结构

代码:

public abstract class Video {
    public abstract void produce();
}
public class JavaVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制javaVideo");
    }
}
public class PythonVideo extends Video {
    @Override
    public void produce() {
        System.out.println("python python");
    }
}
//简单工厂
public class VideoFactory {
      public Video getVideo(String type){
        if("java".equals(type)){
            return new JavaVideo();
        }else if("python".equals(type)){
            return new PythonVideo();
        }
        return null;
   }
  
}


public class Test {
    public static void main(String[] args) {
        VideoFactory videoFactory=new VideoFactory();
        Video video=new JavaVideo();
        video.produce();

        Video v1=videoFactory.getVideo("python");
        if(v1==null){
            return;
       }
        v1.produce();
      
    }
}

简单工厂扩展性太差,用反射进行扩展。

public class VideoFactory {
 public class Test {
    public static void main(String[] args) {
//        VideoFactory videoFactory=new VideoFactory();
//        Video video=new JavaVideo();
//        video.produce();
//
//        Video v1=videoFactory.getVideo("python");
//        if(v1==null){
//            return;
//        }
//        v1.produce();
        VideoFactory videoFactory=new VideoFactory();
        Video video=new JavaVideo();
        video.produce();

        Video v1= null;
        try {
            v1 = videoFactory.getVideo(JavaVideo.class);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        if(v1==null){
            return;
        }
        v1.produce();
    }
}

    //反射来弥补简单工厂的扩展性。
    public Video getVideo(Class  c) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
       Video video=null;
       video=(Video)Class.forName(c.getName()).newInstance();
       return video;
    }
}
public class Test {
    public static void main(String[] args) {
        VideoFactory videoFactory=new VideoFactory();
        Video video=new JavaVideo();
        video.produce();
        Video v1= null;
        try {
            v1 = videoFactory.getVideo(JavaVideo.class);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        if(v1==null){
            return;
        }
        v1.produce();
    }
}

类图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cowafIZM-1606407068554)(G:\研究生课程\第一学期\高级软件设计\photo\06 工厂模式\image-20201126195549467.png)]


工厂方法

定义:

定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。

类型:

创建型

适用场景:

​ 创建对象需要大量重复的代码。

​ 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节

​ 一个类通过其子类来指定创建哪个对象。

优点:

​ 用户只需要关心所需要产品对应的工厂,无需关心创建细节

​ 加入新产品符合开闭原则,提高可扩展性。

​ 如果工厂类有已知的属性方法用抽象类实现工厂,全是未知的属性方法用接口实现。

缺点:

​ 类的个数过多,增加复杂度。

​ 增加了系统的抽象性和理解难度。

代码:

//产品父类
public abstract class Animal{
    public abstract void show();
}
//具体产品1
public class Dog extends Animal {

    @Override
    public void show() {
        System.out.println("Dog");
    }
}

//具体产品2
public class sheep extends Animal {
    @Override
    public void show() {
        System.out.println("sheep");
    }
}

//工厂
public interface AnimalHome {
    public Animal getAnimal();
}

//具体工厂1
public class DogHome implements AnimalHome{
    @Override
    public Animal getAnimal() {
        System.out.println("🐕屋产🐕 dog");
        return new Dog();
    }
}

//具体工厂2
public class SheepHome implements AnimalHome {
    @Override
    public Animal getAnimal() {
        System.out.println("🐏屋产🐏 sheep");
        return new sheep();
    }
}

//测试类
public class TestAnimal {
    public static void main(String[] args) {

        AnimalHome ah=new SheepHome();
        AnimalHome ah2=new DogHome();
        //通过工厂创建对象
        Animal a=ah.getAnimal();
        a.show();
    }
}

类图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y4jhMLxA-1606407068556)(G:\研究生课程\第一学期\高级软件设计\photo\06 工厂模式\image-20201126222559013.png)]


抽象工厂

定义:

​ 抽象工厂模式提供了一个创建一系列相关或相互依赖对象得接口。

​ 无须指定它们具体的类。

类型:

​ 创建型

适用场景:

​ 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。

​ 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。

​ 提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

优点:

​ 具体产品在应用层代码隔离,无须关心创建细节。

​ 一个系列的产品族统一到一起创建。

缺点:

​ 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。

​ 增加了系统的抽象性和理解难度。

工厂方法针对的是产品等级,抽象工厂针对的是产品族。

产品族VS产品等级

产品族:多个产品组成一个产品组:java视频+java代码时同一产品族

产品等级:多个相同等的产品:Java视频Python视频等。

代码:

//相同等级的产品的接口Plant
public interface Plant {
    public void show();
}

//Plant实现一Flower
public class Flower implements Plant {
    @Override
    public void show() {
        System.out.println("很帅的❀儿");
    }
}

//Plant实现二Grass
public class Grass implements Plant {
    @Override
    public void show() {
        System.out.println("一株🎋儿");
    }
}

//相同等级的产品的接口Animal
public interface Animal {
    public void show();
}

//Animal实现一Dog
public class Dog implements Animal {
    @Override
    public void show() {
        System.out.println("一条🐕");
    }
}

//Animal实现二Sheep
public class Sheep implements Animal {
    @Override
    public void show() {
        System.out.println("一只🐏");
    }
}

//抽象工厂接口
public interface Zoo {
    public Animal newAnimal();
    public Plant newPlant();
}

//抽象工厂实现一PPZoo
public class PPZoo implements Zoo{
    //产品族1
    @Override
    public Animal newAnimal() {
        System.out.println("欢迎来到PPZOO,我们的动物有:");
        return new Sheep();
    }

    @Override
    public Plant newPlant() {
        System.out.println("欢迎来到PPZOO,我们的植物有:");
        return new Flower();
    }
}

//抽象工厂实习二LLZoo
public class LLZoo implements Zoo {
    //产品族2
    @Override
    public Animal newAnimal() {
        System.out.println("欢迎来到LLZoo,我们的动物有:");
        return new Dog();
    }

    @Override
    public Plant newPlant() {
        System.out.println("欢迎来到LLZoo,我们的植物有:");

        return new Grass();
    }
}

//测试类

public class testAbstractF {
    public static void main(String[] args) {
        Zoo zoo1 = new LLZoo();//new PPZoo();
        Animal animal1 = zoo1.newAnimal();
        animal1.show();
        Plant plant1 = zoo1.newPlant();
        plant1.show();
        System.out.println("+===============+");
        Zoo zoo2 = new PPZoo();
        Animal animal2 = zoo2.newAnimal();
        animal2.show();
        Plant plant2 = zoo2.newPlant();
        plant2.show();


    }
}


类图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hMQ2KoJJ-1606407068558)(G:\研究生课程\第一学期\高级软件设计\photo\06 工厂模式\image-20201127000314535.png)]

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__0809 返回首页