zoukankan      html  css  js  c++  java
  • 工厂设计模式

      为什么使用工厂模式:工厂是对对象的构造、实例化、初始化过程的一种封装。从而提供给其他需要这些对象的地方去使用,从而降低耦合度,提高扩展性和重用性。如果我们手动的在代码中用new关键字去创建对象,那么就会导致对象的诞生过程会绑定在我们的代码中。宿主类与实例化过程强耦合,后期维护会变得非常麻烦。

    以造车做比喻:现在需要生产不同品牌的车:奔驰,丰田,五菱神车。每种车的价格和属性不一样。

    public abstract class Car {
        private String colour;
        private int price;
        public Car(String colour,int price){
            this.colour=colour;
            this.price=price;
        }
    
        public abstract void run();
    }
    public class BenChiCar extends Car {
        public BenChiCar(String colour,int price){
            super(colour,price);
        }
    
        @Override
        public void run() {
            System.out.println("奔驰在跑");
        }
    }

    省略其他车种的定义

    1、简单工厂:

      所有的对象实例的创建逻辑都写在一个类里

    public class SimpleFactory {
      private String colour;
      private int price;

      public SimpleFactory(String colour, int price) {
      this.colour = colour;
      this.price = price;
      }
      public Car create(String type){
            Car car=null;
            switch (type){
                case "benchi" :
                    car=new BenChiCar(colour,price);
                    break;
                case "fengtian":
                    car=new FengTianCar(colour,price);
                    break;
                case "wuling":
                    car=new WuLingCar(colour,price);
                    break;
            }
            return car;
        }
    }
    public class Client {
        public static void main(String[] args) {
            SimpleFactory simpleFactory = new SimpleFactory("red",100000);
            Car benchi = simpleFactory.create("benchi");
            benchi.run();
            Car wuling = simpleFactory.create("wuling");
            wuling.run();
        }
    }

    简单工厂不能算是设计模式,只是对实例进行了简单的包装而已,客户端依然需要告诉工厂需要生产那种车型,并且工厂生产的车型提前都已经写死在里面,并且随着车型越来越多,这个工厂会越来越庞大,虽然这个过程中没有使用关键字new,但这也是另一种形式的耦合。因此我们应该让我们的工厂可以生产出任意的车型。

    2、工厂方法:

      为了解决上诉问题,我们可以利用多态来实现,即:只提供一个接口,具体的哪类工厂,要自己去实现,一个工厂接口中只有一个工厂方法。

    例如,我们想生产奔驰系列的车,我们就去自己造一个奔驰工厂,想生产丰田系,可以自己造丰田车工厂。甚至自己喜欢,生产特斯拉都可以。

    public interface Factory {
        public Car create(String colour,int price);
    }

    我们想生产奔驰系列

    public class BenChiFactory implements Factory {

    @Override
    public Car create(String colour, int price) {
    return new BenChiCar(colour,price);
    }

    }

    今天高兴想生产台特斯拉

    public class TeSiLaFactory implements Factory {
    
        @Override
        public Car create(String colour, int price) {
            return new TeSiLaCar(colour,price);
        }
    
    }
    public class Client {
        public static void main(String[] args) {
            Factory factory = new BenChiFactory();
            factory.create("red",100);
            Factory factory = new TeSiLaFactory ();
            factory .create("blue",100000);
        }
    }

    工厂方法的好处就是,与其把所有的生产方式都堆积在一个简单工厂类当中,翻来覆去的进行改动。不如把生产方式推迟到子类工厂中去实现,反正工厂本身也是需要进行分类的,这样后期的代码维护以及对新产品的扩展都会更加方便直观。

    3、抽象工厂:

      工厂方法的升级,对整个产品进行横向和纵向拆分,横向划分车种:奔驰、丰田、五菱神车。纵向划分:suv、jiaoche,paoche。

    public interface AbstractFactory {
    
        public Car createSuv();// 工厂方法:制造 SUV
    
        public Car createJiaoche();// 工厂方法:制造 轿车
    
        public Car createChaopao();// 工厂方法:制造 跑车
    }

    这时候,每个车工厂都要实现这三个方法,制造出三种类型的车

    public class Benchi1Factory implements AbstractFactory {
        
        @Override
        public Car createSuv() {
            return new BenChiSuv("white",250000);
        }
    
        @Override
        public Car createJiaoche() {
            return new BenChiJiaoche("black",300000);
        }
    
        @Override
        public Car createChaopao() {
            return new BenChiChaopao("red",900000);
        }
    }

    此时客户端在调用抽象工厂造车时,有了不光有了横向的选择,还有了纵向的选择。

    public class Client2 {
        public static void main(String[] args) {
            AbstractFactory abstractFactory = new BenChiFactory();
            abstractFactory.createSuv();
            abstractFactory.createJiaoche();
        }
    }

    至此,我们用各车工厂对种类繁多的产品进行了划分、归类,产品虽然繁多,但总得有品牌、型号之分,以各族工厂和产品线划界,分而治之,横向拆分产品家族,纵向则拆分产品等级。

  • 相关阅读:
    [BZOJ 1698] 荷叶池塘
    [BZOJ 3132] 上帝造题的七分钟
    [JLOI2011] 飞行路线
    [Codeforces Round49F] Session in BSU
    [BZOJ 3036] 绿豆蛙的归宿
    CRC-16校验原理
    ubuntu下mysql的安装与配置
    【OpenCV】边缘检测:Sobel、拉普拉斯算子
    我对sobel算子的理解
    梯度算子(普通的+Robert + sobel + Laplace)
  • 原文地址:https://www.cnblogs.com/guoyu1/p/11999805.html
Copyright © 2011-2022 走看看