设计模式一——创建型模式(笔记)

简要描述

这些设计模式提供了一种方式:在创建对象的时候隐藏创建逻辑。(不是使用new运算符直接实例化对象)

带来的效果:使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

包括:工厂模式,抽象工厂模式,单例模式,建造者模式,原型模式。

设计模式的六大原则
1、开闭原则:对扩展开发,对修改关闭。用到了接口和抽象类。
2、里氏代换原则:对实现抽象化(基类和子类的继承关系)的具体步骤的规范。
3、依赖倒转原则:针对接口编程,依赖于抽象而非具体。是开闭原则的基础。
4、接口隔离原则:使用多个隔离的接口,降低类间耦合度。
5、迪米特法则(最少知道原则):一个实体尽量少地和其他实体发生相互作用,使得系统功能模块相对独立。
6、合成复用原则:尽量使用合成/聚合,而不是使用继承。

一、工厂模式

介绍:
定义一个创建对象的接口,子类实现工厂接口(自己决定实例化哪一个工厂类)。

优点:
1、调用者创建对象时,只需要知道其名称;
2、扩展性高,增加一个产品只需要扩展一个工厂类;
3、屏蔽了具体实现,调用者只关心接口。

缺点:增加一个产品时,需要加一个具体类和对象实现工厂,使得类的个数成倍增加,从而增加了系统复杂度和系统具体类的依赖。
注:适用于复杂对象的生成。

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

实现:
以创建形状为例
步骤1:创建接口shape.java

public interface Shape {
/**
 * 创建了一个接口
 */
	void draw();
}

步骤2:创建实现接口的实体类RecTangle.java,Square.java,Circle.java

public class RecTangle implements Shape {

	/**
	 * 创建接口的实现类Rectangle
	 */
	@Override
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("Rectangle");
	}

	
}

public class Circle implements Shape {
	/**
	 * 创建接口的实现类Circle
	 */
	@Override
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("Circle");
	}

}

public class Square implements Shape {
/**
 * 创建接口的实现类Square
 */
	@Override
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("Square");
	}

}

步骤3:创建工厂ShapeFactory.java

public class ShapeFactory {

	/**
	 * 创建工厂,生成实体类的对象
	 * @param shapeType
	 * @return
	 */
	public Shape getShape(String shapeType) {
		if(shapeType==null) {
			return null;
		}
		if(shapeType.equals("R")) {
			return new RecTangle();
		}
		if(shapeType.equals("S")) {
			return new Square();
		}
		if(shapeType.equals("C")) {
			return new Circle();
		}
		return null;
	}
}

步骤4:使用工厂(通过传递类型信息获取实体类对象)

public class FactoryTest {

	/**
	 * 测试
	 * 工厂类产生工厂对象
	 * 工厂对象调用工厂内方法来获取实体类对象
	 * @param args
	 */
	public static void main(String[] args) {
		ShapeFactory shapeFactory=new ShapeFactory();
		Shape s1=shapeFactory.getShape("C");
		s1.draw();
		Shape s2=shapeFactory.getShape("R");
		s2.draw();
		Shape s3=shapeFactory.getShape("S");
		s3.draw();
	}
}

二、抽象工厂模式

围绕一个超级工厂(其他工厂的工厂)创建其他工厂。

介绍:
抽象工厂包含许多具体工厂,每一个具体工厂里面有多种具体产品。

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

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

实现:

步骤1:为形状创建一个接口

package implement;

public interface Shape {
/**
 * 创建了一个接口
 */
	void draw();
}

步骤2:创建接口的实现类

package implementclass;
import implement.Shape;

public class RecTangle implements Shape {

	/**
	 * 创建接口的实现类Rectangle
	 */
	@Override
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("Rectangle");
	}
}


package implementclass;
import implement.Shape;

public class Square implements Shape {
/**
 * 创建接口的实现类Square
 */
	@Override
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("Square");
	}

}


package implementclass;
import implement.Shape;

public class Circle implements Shape {
	/**
	 * 创建接口的实现类Circle
	 */
	@Override
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("Circle");
	}

}

步骤3:为颜色创建一个接口

package implement;
public interface Color {

	void fill();
}

步骤4:创建接口的实现类

package implementclass;
import implement.Color;

public class Red implements Color {

	@Override
	public void fill() {
		// TODO 自动生成的方法存根
		System.out.println("红");
	}

}


package implementclass;
import implement.Color;

public class Green implements Color {

	@Override
	public void fill() {
		// TODO 自动生成的方法存根
		System.out.println("绿");
	}

}


package implementclass;
import implement.Color;

public class Blue implements Color{

	@Override
	public void fill() {
		// TODO 自动生成的方法存根
		System.out.println("蓝");
	}

}

步骤5:为形状和颜色对象创建抽象类来获取工厂

package abstractfactory;
import implement.Color;
import implement.Shape;

public abstract class AbstractFactory {

	public abstract Color getColor(String color);
	public abstract Shape getShape(String shape);
}

步骤6:创建抽象类的工厂类

package factoryji;
import abstractfactory.AbstractFactory;
import implement.Color;
import implement.Shape;
import implementclass.Blue;
import implementclass.Green;
import implementclass.Red;

public class ColorFactory extends AbstractFactory{

	@Override
	public Color getColor(String color) {
		// TODO 自动生成的方法存根
		
		if(color==null) {
			return null;
		}
		if(color.equalsIgnoreCase("h")) {
			return new Red();
		}
		if(color.equalsIgnoreCase("g")) {
			return new Green();
		}
		if(color.equalsIgnoreCase("b")) {
			return new Blue();
		}
		return null;
	}

	@Override
	public Shape getShape(String shape) {
		// TODO 自动生成的方法存根
		return null;
	}	
}


package factoryji;
import abstractfactory.AbstractFactory;
import implement.Color;
import implement.Shape;
import implementclass.Circle;
import implementclass.RecTangle;
import implementclass.Square;

public class ShapeFactory extends AbstractFactory {

	/**
	 * 创建工厂,生成实体类的对象
	 * @param shapeType
	 * @return
	 */
	public Shape getShape(String shapeType) {
		if(shapeType==null) {
			return null;
		}
		if(shapeType.equals("r")) {
			return new RecTangle();
		}
		if(shapeType.equals("s")) {
			return new Square();
		}
		if(shapeType.equals("c")) {
			return new Circle();
		}
		return null;
	}

	@Override
	public Color getColor(String color) {
		// TODO 自动生成的方法存根
		return null;
	}
}

步骤7:创建一个工厂生成器类

package vvcreatefactory;

import abstractfactory.AbstractFactory;
import factoryji.ColorFactory;
import factoryji.ShapeFactory;
public class FactoryProducer {

	public static AbstractFactory getFactory(String choice) {
		if(choice.equalsIgnoreCase("shape")) {
			return new ShapeFactory();
		}
		if(choice.equalsIgnoreCase("color")) {
			return new ColorFactory();
		}
		return null;
	}
}

步骤8:测试使用

package abstractfactorytest;

import abstractfactory.AbstractFactory;
import createfactory.FactoryProducer;
import implement.Color;
import implement.Shape;

public class AbstractFactorytest {

	public static void main(String[] args) {
		AbstractFactory shapeFactory = FactoryProducer.getFactory("shape");
		Shape shape1=shapeFactory.getShape("c");
		Shape shape2=shapeFactory.getShape("r");
		Shape shape3=shapeFactory.getShape("s");
		shape1.draw();
		shape2.draw();
		shape3.draw();
		AbstractFactory colorFactory=FactoryProducer.getFactory("color");
		Color color1=colorFactory.getColor("h");
		Color color2=colorFactory.getColor("b");
		Color color3=colorFactory.getColor("g");
		color1.fill();
		color2.fill();
		color3.fill();
	}
}

文件部署
输出结果
三、单例模式

单例类只能有一个实例
单例类必须自己创建自己的唯一实例
单例类必须给所有其他对象提供这一实例

适用时机:控制实例数目,节省系统资源的时候。

优点:
1、减少了内存开销(尤其是频繁的创建和销毁实例)
2、避免对资源的多重占用
缺点:没有接口,不能继承

实现

步骤1:创建一个类

public class SingleObject {

	private static SingleObject instance=new SingleObject();
	private SingleObject() {
	}
	public static SingleObject getInstance() {
		return instance;
	}
	public void showMessage() {
		System.out.println("single");
	}
}

步骤2:获取唯一对象

public class Singletest {

	public static void main() {
		SingleObject object=SingleObject.getInstance();
		object.showMessage();
	}
}

四、建造者模式

使用多个简单的对象一步一步构建成一个复杂的对象。一个Builder类会一步步构造最终对象,该Builder类独立于其他对象。

一个复杂对象由各个部分的子对象以一定算法构成,由于需求变化,复杂对象的各个部分经常发送剧烈变化,但组合在一起的算法相对稳定。

eg:JAVA中的SpringBuilder

优点:
1、易扩展
2、便于控制细节风险
缺点:
1、产品必须由共同点,范围有限
2、如内部变化复杂,会有很多的建造类

使用场景:
1、需要生成的对象具有复杂的内部结构。
2、需要生成的对象内部属性本身相互依赖。

与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

实现:
快餐店案例
步骤1:创建食物条目和食物包装的接口

package implement;

public interface Item {
	public String name();
	public Packing packing();
	public float price();
}

package implement;

public interface Packing {

	public String pack();
}

步骤2:创建实现包装接口的实体类

package implementpacking;

import implement.Packing;

public class Bottle implements Packing{

	@Override
	public String pack() {
		// TODO 自动生成的方法存根
		return "瓶子";
	}
}

package implementpacking;

import implement.Packing;

public class Wrapper implements Packing{

	public String pack() {
		// TODO 自动生成的方法存根
		return "纸袋子";
	}

}

步骤3:创建实现食物条目接口的抽象类

package implementsitemabstract;

import implement.Item;
import implement.Packing;
import implementpacking.Wrapper;

public abstract class Burger implements Item{

	public Packing packing() {
		return new Wrapper();
	}
	public abstract float price();
}

package implementsitemabstract;

import implement.Item;
import implement.Packing;
import implementpacking.Bottle;

public abstract class ColdDrink implements Item{

	public Packing packing() {
		return new Bottle();
	}
	public abstract float price();
	
}

步骤4:创建扩展抽象类的实体类

package entityclass;

import implementsitemabstract.Burger;

public class BurgerChicken extends Burger {

	@Override
	public String name() {
		// TODO 自动生成的方法存根
		return "鸡肉汉堡";
	}

	@Override
	public float price() {
		// TODO 自动生成的方法存根
		return 25.0f;
	}

}


package entityclass;

import implementsitemabstract.Burger;

public class BurgerVeg extends Burger{

	@Override
	public String name() {
		// TODO 自动生成的方法存根
		return "蔬菜汉堡";
	}

	@Override
	public float price() {
		// TODO 自动生成的方法存根
		return 15.0f;
	}
	

}


package entityclass;

import implementsitemabstract.ColdDrink;

public class Doujiang extends ColdDrink{

	@Override
	public String name() {
		// TODO 自动生成的方法存根
		return "豆浆";
	}

	@Override
	public float price() {
		// TODO 自动生成的方法存根
		return 9.0f;
	}

}

package entityclass;

import implementsitemabstract.ColdDrink;

public class Coke extends ColdDrink {

	@Override
	public String name() {
		// TODO 自动生成的方法存根
		return "keke";
	}

	@Override
	public float price() {
		// TODO 自动生成的方法存根
		return 9.0f;
	}

	
}

步骤5:创建一个Meal类

package meallist;

import java.util.ArrayList;
import java.util.List;

import implement.Item;

public class Meal {

	private List<Item> items=new ArrayList<>();
	public void addItem(Item item) {
		items.add(item);
	}
	public float pay() {
		float all=0;
		for(Item item:items) {
			all+=item.price();
		}
		return all;
	}
	public void show() {
		for(Item item:items) {
			System.out.println("清单:"+item.name()+",打包方式"+item.packing().pack()+",总金额"+item.price());
		}
	}
}

步骤6:创建一个MealBuilder类,负责创建Meal

package mealbuilder;

import entityclass.BurgerChicken;
import entityclass.BurgerVeg;
import entityclass.Coke;
import entityclass.Doujiang;
import meallist.Meal;

public class MealBuilder {

	//蔬菜汉堡+可口可乐
	public Meal cookvac() {
		Meal meal=new Meal();
		meal.addItem(new BurgerVeg());
		meal.addItem(new Coke());
		return meal;
		
	}
	//肉汉堡+豆浆
	public Meal cookcad() {
		Meal meal=new Meal();
		meal.addItem(new BurgerChicken());
		meal.addItem(new Doujiang());
		return meal;
		
	}
	
}

步骤7:test

package test;

import mealbuilder.MealBuilder;
import meallist.Meal;

public class BuildTest {

	public static void main(String[] args) {
		MealBuilder mealBuilder=new MealBuilder();
		Meal m1=mealBuilder.cookcad();
		m1.show();
		System.out.println("总价:"+m1.pay());
		Meal m2=mealBuilder.cookvac();
		m2.show();
		System.out.println("总价:"+m2.pay());
	}
}

文件部署
结果输出
五、原型模式

实现一个原型接口用于创建当前对象克隆。

使用场景:
1、资源优化场景。
2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
3、性能和安全要求的场景。
4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
5、一个对象多个修改者的场景。
6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。

注:与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。

实现:
步骤1:创建一个实现Cloneable接口的实现类

package abstractimplement;

public abstract class Shape implements Cloneable{

	private String id;
	protected String type;
	protected abstract void draw();
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public Object clone() {
		Object clone=null;
		try {
			clone = super.clone();
		}catch(CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return clone;
		
	}
	
}

步骤2:创建扩展了上面抽象类的实体类。

package entityclass;

import abstractimplement.Shape;

public class Circle extends Shape {
	public Circle() {
		type="圆";
	}
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("圆");
	}

}
package entityclass;

import abstractimplement.Shape;

public class Rectangel extends Shape{

	public Rectangel() {
		type="三角";
	}
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("三角");
	}
}

package entityclass;

import abstractimplement.Shape;

public class Square extends Shape{

	public Square() {
		type="方";
	}
	public void draw() {
		// TODO 自动生成的方法存根
		System.out.println("方");
	}
}

步骤3:创建一个类,从数据库获取实体类,并把它们存储在一个 Hashtable 中。

package shapecache;

import java.util.Hashtable;

import abstractimplement.Shape;
import entityclass.Circle;
import entityclass.Rectangel;
import entityclass.Square;

public class ShapeCache {

	private static Hashtable<String,Shape> shapeMap=new Hashtable<String,Shape>();
	public static Shape getShape(String shapeId) {
	      Shape cachedShape = shapeMap.get(shapeId);
	      return (Shape) cachedShape.clone();
	   }
	 public static void loadCache() {
	      Circle circle = new Circle();
	      circle.setId("1");
	      shapeMap.put(circle.getId(),circle);
	 
	      Square square = new Square();
	      square.setId("2");
	      shapeMap.put(square.getId(),square);
	 
	      Rectangel rectangle = new Rectangel();
	      rectangle.setId("3");
	      shapeMap.put(rectangle.getId(),rectangle);
	   }
}

步骤 4:使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。

package test;

import abstractimplement.Shape;
import shapecache.ShapeCache;

public class PrototypeTest {

	public static void main(String[] args) {
	      ShapeCache.loadCache();
	 
	      Shape clonedShape = (Shape) ShapeCache.getShape("1");
	      System.out.println("Shape : " + clonedShape.getType());        
	 
	      Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
	      System.out.println("Shape : " + clonedShape2.getType());        
	 
	      Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
	      System.out.println("Shape : " + clonedShape3.getType());        
	   }
}

文件部署
运行结果

啊!再见!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
创建型模式 这些设计模式提供了一种在创建对象的同隐藏创建逻辑的方式,而不是使用 new 运算符直接实例对象。这使得程序判断针对某个给定实例需要创建哪些对象更加灵活。 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern) 2 结构型模式 这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。 适配器模式(Adapter Pattern) 桥接模式(Bridge Pattern) 过滤器模式(Filter、Criteria Pattern) 组合模式(Composite Pattern) 装饰器模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 代理模式(Proxy Pattern) 3 行为型模式 这些设计模式特别关注对象之间的通信。 责任链模式(Chain of Responsibility Pattern) 命令模式(Command Pattern) 解释器模式(Interpreter Pattern) 迭代器模式(Iterator Pattern) 中介者模式(Mediator Pattern) 备忘录模式(Memento Pattern) 观察者模式(Observer Pattern) 状态模式(State Pattern) 空对象模式(Null Object Pattern) 策略模式(Strategy Pattern) 模板模式(Template Pattern) 访问者模式(Visitor Pattern) 4 J2EE 模式 这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。 MVC 模式(MVC Pattern) 业务代表模式(Business Delegate Pattern) 组合实体模式(Composite Entity Pattern) 数据访问对象模式(Data Access Object Pattern) 前端控制器模式(Front Controller Pattern) 拦截过滤器模式(Intercepting Filter Pattern) 服务定位器模式(Service Locator Pattern) 传输对象模式(Transfer Object Pattern)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值