设计模式总概念之创建型设计模式详解
设计模式分类:
创建型设计模式:对象怎么来的,主要用于创建对象。
结构型设计模式:对象和谁有关系,主要用于描述对象之间的关系。
行为型设计模式:对象和对象在干嘛,主要用于描述对象的动作。
J2EE型设计模式:对象联合起来要干嘛,主要用于描述对象联合的目的。
设计模式的六大原则:
开闭原则:对扩展开放,对修改关闭。
里氏代换原则:任何基类可以出现的地方,子类一定可以出现
依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体类
接口隔离原则:使用多个隔离的接口好过于使用一个接口,降低类之间的耦合性
迪米特法则:实体之间尽少相互作用,系统功能模块尽量独立;
合成复用原则:尽量使用聚合和组合,而不是继承;
创建型设计模式:
工厂模式 ; 抽象工厂模式 ; 单例模式 ; 建造者模式 ; 原型模式
工厂模式:
创建一个接口,创建多个实现接口的实体类
创建一个工厂类,通过工厂创建对象。
定义Animal接口: Animal.java
public interface Animal
{
void eat();
}
定义接口实现类1 Dog.java
public class Dog implements Animal
{
@Override
public void eat()
{
System.out.println("eat meat ~");
}
}
定义接口实现类2 Cat.java
public class Cat implements Animal { @Override public void eat() { System.out.println("eat fish ~"); } }
定义工厂类 AnimalFactory.java
public class AnimalFactory { public AnimalFactory getAnimalFactory(String animalName)
{
if(animalName.equalsIgnoreCase("DOG"))
{
return new Dog();
}
else if(animalName.equalsIgnoreCase("Cat"))
{
return new Cat();
}
else
{
return null;
}
}
}
通过工厂类创建对象类 AnimalFactoryTest.java
public class AnimalFactoryTest { public static void main(String[] args) {
//创建工厂对象 AnimalFactory animalFactory = new AnimalFactory();
//通过工厂对象创建对应的接口实现类对象,而后调用类实现的方法
Dog dog = animalFactory.getAnimalFactory("dog");
dog.eat();
Cat cat= animalFactory.getAnimalFactory("cat");
cat.eat();
} }
输出结果为:
eat meat ~
eat fish ~
抽象工厂模式:
创建多个接口,创建对应每个接口的多个实现类
创建一个抽象工厂类 里面包含得到每个接口类型变量的抽象方法
创建多个工厂继承抽象工厂,实现对应的方法,不对应的采用空实现
与工厂模式的不同之处: 接口对应的工厂类继承抽象工厂,工厂生成器生成工厂,再通过工厂创建对象
定义Shape接口: Shape.java
public interface Shape { void draw(); }
定义Circle实现SHape接口类: Circle.java
public class Circle implements Shape { public void draw()
{ System.out.println("draw--circle"); } }
定义Square实现SHape接口类: Square.java
public class Square implements Shape
{
public void draw()
{
System.out.println("draw--square");
}
}
定义Color接口: Color.java
public interface Color
{
void fill();
}
定义Red实现Color接口类: Red.java
public class Red implements Color
{
public void fill()
{
System.out.println("fill--Red");
}
}
定义Green实现Color接口类: Green.java
public class Green implements Color
{
public void fill()
{
System.out.println("fill--green");
}
}
创建获取接口的抽象工厂: AbstractFactory.java
public abstract class AbstractFactory { abstract Shape getShape(String shape); abstract Color getColor(String color); }
创建Shape接口对应的工厂,并且继承抽象工厂: ShapeFactory.java
public class ShapeFactory extends AbstractFactory { @Override public Shape getShape(String shape) { if(shape.equals("Circle"){ return new Circle(); }else if(shape.equals("Square")){ return new Square(); }else{ return null; } }
@Override
public Color getColor(String color)
{
return null;
}
}
创建Color接口对应的工厂,并且继承抽象工厂:ColorFactory.java
public class ColorFactory extends AbstractFactory
{
@Override
public Color getColor(String color)
{
if(color.equals("red"){
return new Red();
}else if(color.equals("green")){
return new Green();
}else{
return null;
}
}
@Override
public Shape getShape(String shape)
{
return null;
}
}
创建工厂生成器类用来得到相应的接口对应的工厂: BuilderFactory.java
public class BuilderFactory { public static AbstractFactory getFactory(String factory) { if(factory.equals("ShapeFactory")){ return new ShapeFactory(); }else if(factory.equals("ColorFactory")){ return new ColorFactory(); }else{ return null; } } }
测试类:AbstractFactoryTest.java
public class AbstractFactoryTest {
public static void main(String[] args){
//得到Shape接口对应的工厂
AbstractFactory shapeFactory = BuilderFactory.getFactory("ShapeFactory");
//通过工厂创建Circle对象
Circle circle = shapeFactory.getShape("Circle");
circle.draw();
//通过工厂创建Square对象
Square square= shapeFactory.getShape("Square");
square.draw();
//得到Color接口对应的工厂
AbstractFactory colorFactory = BuilderFactory.getFactory("ColorFactory");
//通过工厂创建Red对象
Red red= colorFactory .getColor("red");
red.fill();
//通过工厂创建Green对象
Green green= colorFactory .getColor("green");
green.fill();
}
}
输出结果为:
draw--circle
draw--square
fill--red
fill--green
单例模式:
保证只有一个对象的存在
构造方法私有化
饱汉式单例与饿汉式单例
包汉式单例 Singleton.java
特点:
创建静态全局变量
定义私有构造方法
创建静态方法获取对象,先判断对象是否存在,存在直接返回对象,不存在通过new创建对象再返回。
public class Singleton { private static Singleton instance; private Singleton (){}
//synchronized存在的时候表示这是线程安全的,不存在的时候表示线程不安全 public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }
public void showMessage(){
System.out.println("Hello World!");
}
}
饿汉式单例:Singleton.java
特点:
定义私有的构造方法
直接定义静态全局变量并且创建对象为其赋值,
创建静态方法获取时直接返回对象。
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; }
public void showMessage(){
System.out.println("Hello World!");
}
}
测试类: SingletonTest.java
public class SingletonTest{ public static void main(String[] args) { //不合法的构造函数 //编译时错误:构造函数 Singleton () 是不可见的 //Singleton object = new Singleton (); //获取唯一可用的对象 Singleton object = Singleton .getInstance(); //显示消息 object.showMessage(); } }
输出结果:
Hello world!
知识点:抽象类实现接口可以不实现的接口的所有方法,未实现的接口方法可以交给抽象类的子类去实现。
建造者模式:
使用多个简单的对象一步一步构建成一个复杂的对象。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
步骤 1
创建一个表示食物条目和食物包装的接口。
Item.java
public interface Item {
public String name();
public Packing packing();
public float price();
}
Packing.java
public interface Packing {
public String pack();
}
步骤 2
创建实现 Packing 接口的实体类。
Wrapper.java
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
Bottle.java
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
步骤 3
创建实现 Item 接口的抽象类,该类提供了默认的功能。(这里只实现一个方法,其余两个交给子类去实现)
Burger.java
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
ColdDrink.java
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
步骤 4
创建扩展了 Burger 和 ColdDrink 的实体类。
VegBurger.java
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
ChickenBurger.java
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
Coke.java
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
Pepsi.java
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
步骤 5
创建一个 Meal 类,带有上面定义的 Item 对象。
Meal.java
import java.util.ArrayList;
import java.util.List;
public class Meal {
private List<Item> items = new ArrayList<Item>();
public void addItem(Item item){
items.add(item);
}
public float getCost(){
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems(){
for (Item item : items) {
System.out.print("Item : "+item.name());
System.out.print(", Packing : "+item.packing().pack());
System.out.println(", Price : "+item.price());
}
}
}
步骤 6
创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。
MealBuilder.java
public class MealBuilder {
public Meal prepareVegMeal (){
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonVegMeal (){
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
步骤 7
BuiderPatternDemo 使用 MealBuider 来演示建造者模式(Builder Pattern)。
BuilderPatternDemo.java
public class BuilderPatternDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " +vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " +nonVegMeal.getCost());
}
}
步骤 8
验证输出。
Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0
Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5