[设计模式] 创建型
简单工厂模式
简单工厂模式又称为静态工厂模式,简单工厂模式的作用就是创建一个工厂类用来创建其它类的实例,至于类是怎么样创建的对用户来说是不可见的「屏蔽细节」
类似于生活中的工厂
我认为工厂模式是为了方便快捷地实例特定参数的类
其UML图也很简单
所以我们甚至不用来阅读代码,只需要看包结构即可明白他们各有什么作用
Product -- 抽象产品
Product1、Product2 --具体产品
simFactory1 --简单工厂
通常我们会在工厂类的方法里加一个判断,对应着不同原料生产不同的产品
public class simFactory1 { public static Product creatProduct(String type) {// 判断语句 if (type.equals("A")) { return new Product1(); } else { return new Product2();}} public static void main(String[] args) { Product product = simFactory1.creatProduct("B"); product.print(); } }
工厂模式
与简单工厂相比,也就是将工厂所做的工作分包出去了。本来原料A进来需要在工厂类中进行加工,现在工厂类中的方法也变得抽象,通过接口分包出去。就好像贴牌工厂一样,实际没有具体生产任务
使用工厂方法创建车船
其中Factory和Product都是抽象接口类,一个是抽象工厂一个是抽象产品。
其中我们需要创建什么产品就访问什么工厂而不需要管其他
抽象工厂模式
也就是说将工厂类更加复杂化了,里面可以生产更多抽象
这里写了一个利用抽象工厂造车造手机的方法,可以看到实质上有三个接口,工厂、车、手机,写成抽象类应该也行,但是接口好像更方便
public class SuperFactory implements Factory{ @Override public Car createCar(Integer s) { if (s >= 5) { return new BMW(); } else { return new BC(); } } @Override public Phone createPhone(Integer s) { if (s >= 5) { return new huaiwei(); } else { return new xiaomi(); }}}
在具体工厂我们可以看到,实际上有一个逻辑上的判断,传进来的值是多少决定了所返回的实体类
建造者模式
产品需要有共同点,将构建代码与调用代码分离。
我们先来看一个盖房子的例子:
上面的流程梳理一下,一共有5个角色
用户:也就是我们消费者,用户提要求,要建一个什么样的房子
Director(开发商):他自己不会开发,就像万达老板一样可能不会砌墙这些,但是他找包工头去做,他只需要去调用这些包工头就造房子就好了。
Builder(抽象的包工头):给出一个抽象接口,规定房子由哪几部分组成,如何去建造。给下面的包工头一个建房子的规范。
ContreteBuilder(具体包工头):真正建房子的人,但是每一个包工头可以建不同的房子。
Product(房子):也就是我们的产品类。
再给出一张类图看一下他们几个在类上的关系
原型模式
这个模式的核心在于实现类集成了一个接口,内含克隆方法
@Override public Object clone() { return new Plane(this); }
该方***将对象本身返回,我们可以看这样一段代码
public class Plane implements proto{ private String name; private String age; public Plane() { name = "波音" + Math.random(); age = "服役了" + Math.random() + "年"; } public Plane(Plane plane) { this.name = plane.name; this.age = plane.age; } public String getName() { return name; } public String getAge() { return age; } @Override public String toString() { return "Plane{" + "name='" + name + '\'' + ", age='" + age + '\'' + '}'; } @Override public Object clone() { return new Plane(this); } }
这里我们看到,其实这个创建方法并没有留set方法,并且生成的属性也是随机的。我们怎么获取一个一模一样的对象呢? 重写其中的clone方法即可。
+
练习
1.使用简单工厂模式
实现女娲(Nvwa)造人(Person),若传入W,则返回man对象,若传入W,则返回woman对象,若传入R则返回robot对象。
这里使用简单工厂模式是非常容易的,可见包结构,其中Nvwa为工厂类,而Person为抽象接口,其余为其实现
2. 使用工厂模式作一个图片阅读器
其中imageReaderFactory为接口,image为抽象类,GIF JPG为具体实现类。
3. 原型模式
private String address = "ss469469ssss"; public Customer() { this.address = address; } public Object clone() { Object obj = null; try { obj = super.clone(); } catch (CloneNotSupportedException e) { System.out.println("克隆失败");;} return obj;} @Override public String toString() { return "Customer{" +"address='" + address + '\'' +'}';}
这是使用浅克隆模式进行克隆,还有一种方法为深克隆模式,即克隆对象又克隆容器。
下面是进行深克隆模式的代码
public class Customser2 implements Serializable { private String address = "1361616516"; public Customser2() { this.address = address; } public Object deepClone() throws IOException, ClassCastException, OptionalDataException, ClassNotFoundException { ByteArrayOutputStream bao = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bao); oos.writeObject(this); ByteArrayInputStream bai = new ByteArrayInputStream(bao.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bai); Object o = ois.readObject(); return o; } @Override public String toString() { return "Customser2{" + "address='" + address + '\'' + '}'; } }