设计模式工厂模式-原型模式

Java设计模式

  • 简单工厂模式
    • 基本介绍:

      • 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。
      • 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为。
      • 在软件开发中,当我们会用到大量的创建某种,某类或者某批对象时,就会使用工厂模式。
    • 静态工厂模式

        public abstract class Pizza {
        	protected String name;
        	public abstract void prepare();
        	public void bake() {
        		System.out.println(name+"baking");
        	}
        	public void cut() {
        		System.out.println(name+"cutting");
        	}
        	public void box() {
        		System.out.println(name+"boxing");
        	}
        	public void setName(String name) {
        		this.name = name;
        	}
        }
        public class CheesePizza extends Pizza{
        	@Override
        	public void prepare() {
        		System.out.println("奶酪披萨准备原材料");
        	}
        }
        public class GreekPizza extends Pizza{
        	@Override
        	public void prepare() {
        		System.out.println("希腊披萨准备原材料");
        	}
        }
        public class PepperPizza extends Pizza {
        	@Override
        	public void prepare() {
        		System.out.println("胡椒披萨正在准备原材料");
        	}
        }
        //简单工厂了类
        public class SimpleFactory {
        	public  static Pizza createPizza(String orderType) {
        		Pizza pizza=null;
        		System.out.println("使用简单工厂模式");
        		if("greek".equals(orderType)) {
        			pizza=new GreekPizza();
        			pizza.setName("希腊披萨");
        		}else if ("cheese".equals(orderType)) {
        			pizza=new CheesePizza();
        			pizza.setName("奶酪披萨");
        		}else if ("pepper".equals(orderType)) {
        			pizza=new PepperPizza();
        			pizza.setName("胡椒披萨");
        		}
        		if(pizza!=null) {
        			printPizza(pizza);
        		}else {
        			System.out.println("订购失败");
        		}
        		return pizza;
        	}
        
        	private static void printPizza(Pizza pizza) {
        		pizza.prepare();
        		pizza.bake();
        		pizza.cut();
        		pizza.box();
        	}
        }
        public class PizzaStore {
        	public static void main(String[] args) {
        		new OrderPizza().orderPizza();
        		System.out.println("退出程序");
        	}
        }
      
    • 工厂方法模式

      • 基本介绍:定义一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类

      • 代码

          public abstract class Pizza {
          	protected String name;
          	public abstract void prepare();
          	public void bake() {
          		System.out.println(name+"baking");
          	}
          	public void cut() {
          		System.out.println(name+"cutting");
          	}
          	public void box() {
          		System.out.println(name+"boxing");
          	}
          	public void setName(String name) {
          		this.name = name;
          	}
          }
          public class BJCheesePizza extends Pizza{
          	@Override
          	public void prepare() {
          		setName("北京的奶酪披萨");
          		System.out.println("北京的奶酪披萨准备原材料");
          	}
          }
          public class BJPepperPizza extends Pizza{
          	@Override
          	public void prepare() {
          		setName("北京的胡椒披萨");
          		System.out.println("北京的胡椒披萨准备原材料");
          	}
          }
          public class LDCheesePizza extends Pizza{
          	@Override
          	public void prepare() {
          		setName("北京的奶酪披萨");
          		System.out.println("北京的奶酪披萨准备原材料");
          	}
          }
          public class LDPepperPizza extends Pizza{
          	@Override
          	public void prepare() {
          		setName("北京的胡椒披萨");
          		System.out.println("北京的胡椒披萨准备原材料");
          	}
          }
          public  class BJOrderPizza extends OrderPizza{
          
          	@Override
          	Pizza createPizza(String orderType) {
          		Pizza pizza=null;
          		if(orderType.equals("cheese")) {
          			pizza=new BJCheesePizza();
          		}else if(orderType.equals("pepper")) {
          			pizza=new BJPepperPizza();
          		}
          		return pizza;
          	}
          }
          public  class LDOrderPizza extends OrderPizza {
          	@Override
          	Pizza createPizza(String orderType) {
          		Pizza pizza=null;
          		if(orderType.equals("cheese")) {
          			pizza=new LDCheesePizza();
          		}else if(orderType.equals("pepper")) {
          			pizza=new LDPepperPizza();
          		}
          		return pizza;
          	}
          }
          public abstract class OrderPizza {
          	 OrderPizza(){
          		Pizza pizza=null;
          		String orderType;
          			do {
          				orderType=getType();
          				pizza=createPizza(orderType);
          				pizza.prepare();
          				pizza.bake();
          				pizza.cut();
          				pizza.box();
          			} while (true);
          	}
          	abstract Pizza createPizza(String orderType);
          	private String getType() {
          		BufferedReader strin=new BufferedReader(new InputStreamReader(System.in));
          		System.out.println("input pizza type:");
          		try {
          			String str=strin.readLine();
          			return str;
          		} catch (IOException e) {
          			e.printStackTrace();
          			return "";
          		}
          	}
          
          }
          public class PizzaStore {
          	public static void main(String[] args) {
          		//创建北京的口味披萨
          		new BJOrderPizza();
          	}
          }
        
    • 抽象工厂模式

      • 基本介绍:定义一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类

      • 抽象工厂模式可以将简单工厂模式和工厂方法模进行整合。

      • 从设计层面看抽象工厂模式就是对简单工厂模式的改进(或者称为进一步抽象)

      • 将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

      • 代码

          public abstract class Pizza {
          	protected String name;
          	public abstract void prepare();
          	public void bake() {
          		System.out.println(name+"baking");
          	}
          	public void cut() {
          		System.out.println(name+"cutting");
          	}
          	public void box() {
          		System.out.println(name+"boxing");
          	}
          	public void setName(String name) {
          		this.name = name;
          	}
          }
          public class BJCheesePizza extends Pizza{
          	@Override
          	public void prepare() {
          		setName("北京的奶酪披萨");
          		System.out.println("北京的奶酪披萨准备原材料");
          	}
          }
          public class BJPepperPizza extends Pizza{
          	@Override
          	public void prepare() {
          		setName("北京的胡椒披萨");
          		System.out.println("北京的胡椒披萨准备原材料");
          	}
          }
          public class LDCheesePizza extends Pizza{
          	@Override
          	public void prepare() {
          		setName("伦敦的奶酪披萨");
          		System.out.println("伦敦的奶酪披萨准备原材料");
          	}
          }
          public class LDPepperPizza extends Pizza{
          	@Override
          	public void prepare() {
          		setName("伦敦的胡椒披萨");
          		System.out.println("伦敦的胡椒披萨准备原材料");
          	}
          }
          /**
           * 抽象工厂模式的接口
           * @author Administrator
           *
           */
          public interface AbsFactory {
          	public Pizza createPizza(String orderType);
          }
          public class BJFactory implements AbsFactory {
          	@Override
          	public Pizza createPizza(String orderType) {
          		Pizza pizza=null;
          		if(orderType.equals("cheese")) {
          			pizza=new BJCheesePizza();
          		}else if(orderType.equals("pepper")) {
          			pizza=new BJPepperPizza();
          		}
          		return pizza;
          	}
          }
          public class LDFactory implements AbsFactory {
          	@Override
          	public Pizza createPizza(String orderType) {
          		Pizza pizza=null;
          		if(orderType.equals("cheese")) {
          			pizza=new LDCheesePizza();
          		}else if(orderType.equals("pepper")) {
          			pizza=new LDPepperPizza();
          		}
          		return pizza;
          	}
          }
          public class OrderPizza {
          	AbsFactory factory;
          	public void setFactory(AbsFactory factory) {
          		this.factory=factory;
          		Pizza pizza=null;
          		String orderType;
          		do {
          			orderType=getType();
          			pizza=factory.createPizza(orderType);
          			if(pizza!=null) {
          				pizza.prepare();
          				pizza.bake();
          				pizza.cut();
          				pizza.box();
          			}else {
          				System.out.println("订购失败");
          				break;	
          			}
          
          		} while (true);
          	}
          	private String getType() {
          		BufferedReader strin=new BufferedReader(new InputStreamReader(System.in));
          		System.out.println("input pizza type:");
          		try {
          			String str=strin.readLine();
          			return str;
          		} catch (IOException e) {
          			e.printStackTrace();
          			return "";
          		}
          	}
          }
          public class PizzaStore {
          	public static void main(String[] args) {
          		//创建北京的口味披萨
          		new OrderPizza().setFactory(new BJFactory());
          		//创建伦敦的口味披萨
          		//new OrderPizza().setFactory(new LDFactory());
          		System.out.println("退出程序");
          	}
          }
        
    • 工厂模式小结

      • 工厂模式的意义:将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系解耦。从而提高项目的扩展和维护性。
      • 三种工厂模式
      • 设计模式的依赖抽象原则
    • 注意事项

      • 创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回。
      • 不要让类继承具体类,而是继承抽象类或者是实现interface(接口)
      • 不要覆盖基类中已经实现的方法。
  • 原型模式
    • 基本介绍:

      • 原型模式是指:用原型实例指定对象的种类,并且通过拷贝这些原型,创建新对象。
      • 原型模式是一种创建型设计模式,允许一个对象在创建另一个可制定的对象,无需知道如何创建的细节。
      • 工作原理:通过将一个原型对象传给那个要发动创建的对象,这个要创建的对象通过请求原型对象拷贝他们自己来实现创建,即对象.clone()
    • 代码

        public class Sheep implements Cloneable{
        	private String name;
        	private int age;
        	private String color;
        	public Sheep(String name, int age, String color) {
        		super();
        		this.name = name;
        		this.age = age;
        		this.color = color;
        	}
        	public String getName() {
        		return name;
        	}
        	public void setName(String name) {
        		this.name = name;
        	}
        	public int getAge() {
        		return age;
        	}
        	public void setAge(int age) {
        		this.age = age;
        	}
        	public String getColor() {
        		return color;
        	}
        	public void setColor(String color) {
        		this.color = color;
        	}
        	
        	@Override
        	public String toString() {
        		return "Sheep [name=" + name + ", age=" + age + ", color=" + color + "]";
        	}
        	//克隆该实例,使用默认的clone方法来完成
        	@Override
        	protected Sheep clone() {
        		Sheep sheep=null;
        		try {
        			sheep=(Sheep) super.clone();
        		} catch (CloneNotSupportedException e) {
        			System.out.println(e.getMessage());
        		}
        		return sheep;
        	}
        }
        public class Client {
        
        	public static void main(String[] args) {
        		System.out.println("用原型模式克隆对象");
        		Sheep sheep=new Sheep("tom", 1,"黑色");
        		Sheep sheep1=sheep.clone();
        		Sheep sheep2=sheep.clone();
        		Sheep sheep3=sheep.clone();
        		Sheep sheep4=sheep.clone();
        		System.out.println(sheep);
        		System.out.println(sheep1);
        		System.out.println(sheep2);
        		System.out.println(sheep3);
        		System.out.println(sheep4);
        	}
        }
      
    • 浅拷贝和深拷贝

      • 浅拷贝

        • 对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象
        • 对于数据类型是引用数据类型的成员变,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量。
        • 前边我们克隆羊就是浅拷贝
        • 浅拷贝的使用默认的clone()方法实现
      • 深拷贝

        • 复制对象的所有基本数据类型的成员变量值
        • 为所有的数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象进行拷贝。
        • 深拷贝对象的方式1:重写clone方法来实现深拷贝
        • 深拷贝实现方式2:通过对象序列化实现深拷贝
      • 深度克隆的两种方式

          package prototype.deepClone;
          
          import java.io.ByteArrayInputStream;
          import java.io.ByteArrayOutputStream;
          import java.io.ObjectInputStream;
          import java.io.ObjectOutputStream;
          import java.io.Serializable;
          
          /**
           * 深拷贝的clone方法和序列化方法
           * @author Administrator
           *
           */
          public class Person implements Cloneable,Serializable{
          	private static final long serialVersionUID = -3286376603429170935L;
          	private String name;
          	private int age;
          	private Address address;
          	public String getName() {
          		return name;
          	}
          	public void setName(String name) {
          		this.name = name;
          	}
          	public int getAge() {
          		return age;
          	}
          	public void setAge(int age) {
          		this.age = age;
          	}
          	public Address getAddress() {
          		return address;
          	}
          	public void setAddress(Address address) {
          		this.address = address;
          	}
          	@Override
          	public String toString() {
          		return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
          	}
          	//深拷贝的第一种方式
          	@Override
          	protected Object clone() {
          		Object deep=null;
          		try {
          			deep=super.clone();
          			Person person=(Person)deep;
          			person.address=(Address)address.clone();
          		} catch (Exception e) {
          			System.out.println(e.getMessage());
          		}
          		return deep;
          	}
          	//深拷贝的第二种方式
          	public Object deepClone() {
          		ByteArrayOutputStream bos = null;
          		ObjectOutputStream oos=null;
          		ByteArrayInputStream bis=null;
          		ObjectInputStream ois=null;
          		try {
          			//序列化
          			bos=new ByteArrayOutputStream();
          			oos=new ObjectOutputStream(bos);
          			oos.writeObject(this);
          			//反序列化
          			bis=new ByteArrayInputStream(bos.toByteArray());
          			ois=new ObjectInputStream(bis);
          			return ois.readObject();
          		} catch (Exception e) {
          			System.err.println(e.getMessage());
          			return null;
          		}finally {
          			try {
          				bos.close();
          				oos.close();
          				bis.close();
          				ois.close();
          			} catch (Exception e) {
          				System.out.println(e.getMessage());
          			}
          		}
          		
          	}
          
          }
          package prototype.deepClone;
          
          import java.io.Serializable;
          
          public class Address implements Cloneable,Serializable{
          	private static final long serialVersionUID = 7744431983340465732L;
          	private String name;
          	private int id;
          	public Address(String name, int id) {
          		super();
          		this.name = name;
          		this.id = id;
          	}
          	public String getName() {
          		return name;
          	}
          	public void setName(String name) {
          		this.name = name;
          	}
          	public int getId() {
          		return id;
          	}
          	public void setId(int id) {
          		this.id = id;
          	}
          	@Override
          	public String toString() {
          		return "Address [name=" + name + ", id=" + id + "]";
          	}
          	@Override
          	protected Address clone() throws CloneNotSupportedException {
          		return (Address)super.clone();
          	}
          
          }
          package prototype.deepClone;
          
          public class Client {
          
          	public static void main(String[] args) {
          		System.out.println("深拷贝对象");
          		Person p = new Person();
          		p.setName("松江");
          		p.setAge(1);
          		p.setAddress(new Address("山西",1));
          		Person p2 =(Person)p.clone();
          		//通过序列化实现深拷贝
          		Person p3 =(Person)p.deepClone();
          		System.out.println(p+"-----"+p.getAddress().hashCode());
          		System.out.println(p2+"-----"+p2.getAddress().hashCode());
          		System.out.println(p3+"-----"+p3.getAddress().hashCode());
          	}
          }	
        
    • 原型模式的注意事项和细节

      • 创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
      • 不用重新初始化对象,而是动态的获得对象运行时的状态
      • 如果原始对象发生变化,其它克隆对象也会发生相应的变化,而无需修改代码
      • 在实现深度克隆的时候可能需要比较复杂的代码
      • 缺点:需要为每个类配备一个克隆方法,这对全新的类来说不是很难,但对已有的类进行改造时,需要修改其源码,违背了ocp原则
发布了25 篇原创文章 · 获赞 1 · 访问量 760
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览