创建型模式
创建型模式的作用就是创建对象,说到创建一个对象,最熟悉的就是new一个对象,然后set相关属性。但是,在很多场景下,我们需要给客户端提供更加友好的创建对象的方式,尤其是那种定义了类,但是需要提供给其他开发者用的时候。
1、简单工厂模式
让子类决定创建哪个对象
interface Shape {
void draw();
}
class Rectangle implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
}
}
class Square implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
}
}
class Circle implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
}
}
class ShapeFactory {
public static Shape getShare(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equals("CIRCLE")) {
return new Circle();
} else if (shapeType.equals("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}
简单工厂模式通常就是一个工厂类***Factory,里面有一个静态方法,根据不同的参数,返回不同的派生自同一个父类的实例对象。
2、抽象工厂模式
创建多个产品族中的产品对象
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
我们将创建Shape和Color接口和实现这些接口的实体类。下一步是创建抽象工厂类AbstractFactory。接着定义工厂类ShapeFactory和ColorFactory,这两个工厂类都是扩展了AbstractFactory。然后创建一个工厂创造器/生成器类FactoryProducer
interface Shape {
void draw();
}
class Rectangle implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
}
}
class Square implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
}
}
class Circle implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
}
}
interface Color {
void fill();
}
class Red implements Color {
@Override
public void fill() {
// TODO Auto-generated method stub
}
}
class Green implements Color {
@Override
public void fill() {
// TODO Auto-generated method stub
}
}
class Blue implements Color {
@Override
public void fill() {
// TODO Auto-generated method stub
}
}
abstract class AbstractFactory {
abstract Color getColor(String color);
abstract Shape getShape(String shape);
}
class ShapeFactory extends AbstractFactory {
@Override
Color getColor(String color) {
// TODO Auto-generated method stub
return null;
}
@Override
Shape getShape(String shape) {
// TODO Auto-generated method stub
return null;
}
}
class ColorFactory extends AbstractFactory {
@Override
Color getColor(String color) {
// TODO Auto-generated method stub
return null;
}
@Override
Shape getShape(String shape) {
// TODO Auto-generated method stub
return null;
}
}
class FactoryProducer {
public static AbstractFactory getFactory(String choice) {
if (choice.equalsIgnoreCase("SHAPE")) {
return new ShapeFactory();
} else if (choice.equalsIgnoreCase("COLOR")) {
return new ColorFactory();
}
return null;
}
}
3、单例模式
确保某一个类只有一个实例,并且提供一个全局访问点
懒汉式,线程不安全
public class Singleton {
private static Singleton sInstance;
private Singleton() {
}
public static Singleton getInstance() {
if (sInstance == null) {
sInstance = new Singleton();
}
return sInstance;
}
}
懒汉式,线程安全
public class Singleton {
private static Singleton sInstance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (sInstance == null) {
sInstance = new Singleton();
}
return sInstance;
}
}
饿汉式
public class Singleton {
private static Singleton sInstance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return sInstance;
}
}
双检锁/双重校验锁
public class Singleton {
private static volatile Singleton sInstance;
private Singleton() {
}
public static Singleton getInstance() {
if (sInstance == null) {
synchronized (Singleton.class) {
if (sInstance == null) {
sInstance = new Singleton();
}
}
}
return sInstance;
}
}
登记式/静态内部类
public class Singleton {
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.sInstance;
}
}
枚举
public enum Singleton {
INSTANCE;
public void method() {
}
}
4、建造者模式
用来创建复杂的复合对象
建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。将一个复杂的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
public class User {
private String name;
private String password;
private String nickname;
private int age;
private User(String name, String password, String nickname, int age) {
this.name = name;
this.password = password;
this.nickname = nickname;
this.age = age;
}
public static UserBuilder builder() {
return new UserBuilder();
}
public static class UserBuilder {
private String name;
private String password;
private String nickname;
private int age;
private UserBuilder() {
}
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder password(String password) {
this.password = password;
return this;
}
public UserBuilder nickname(String nickname) {
this.nickname = nickname;
return this;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public User build() {
return new User(name, password, nickname, age);
}
}
}
User user = User.builder()
.name("lilei")
.age(10)
.nickname("xulei")
.password("100")
.build();
5、原型模式
通过复制原型来创建新对象
原型模式是用于创建重复的对象,同时又能保证性能。
关键代码实现克隆操作,在Java集成Cloneable,重写Clone()
创建型模式总结
创建型模式总体上比较简单,它们的作用就是为了产生实例对象,算是各种工作的第一步了,因为我们写的是面向对象的代码,所以我们第一步当然是需要创建一个对象了。
结构型模式
结构型模式旨在通过改变代码结构来达到解耦的目的,使得我们的代码容易维护和扩展
6、代理模式
控制客户端对对象的访问
public interface Image {
void display();
}
public class RealImage implements Image{
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
private void loadFromDisk(String fileName) {
System.out.println("Loading " + fileName);
}
}
public class ProxyImage implements Image {
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName) {
this.fileName = fileName;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(fileName);
}
realImage.display();
}
}
public class ProxyPatternDemo {
public static void main(String[] args) {
ProxyImage image = new ProxyImage("test_10mb.jpg");
image.display();
}
}
7. 适配器模式
将原来不兼容的两个类融合在一起
适配器模式是作为两个不兼容的接口之间的桥梁。
默认适配器模式
对象适配器模式
public interface Cock {
public void gobble();
public void fly();
}
public interface Duck {
public void quack();
public void fly();
}
public class WildCock implements Cock {
@Override
public void gobble() {
System.out.println("gugujiao");
}
@Override
public void fly() {
System.out.println("feifeifei");
}
}
public class CockAdapter implements Duck {
private Cock cock;
public CockAdapter(Cock cock) {
this.cock = cock;
}
@Override
public void quack() {
cock.gobble();
}
@Override
public void fly() {
cock.fly();
}
}
适配器模式总结:
1、类适配和对象适配的异同
一个采用继承,一个采用组合;
类适配属于静态实现,对象适配属于组合的动态实现,对象适配需要多实例化一个对象。
总体来说,对象适配用得比较多。
2、适配器模式和代理模式的异同
比较这两种模式,其实是比较对象适配器模式和代理模式,在代码结构上,它们很相似,都需要一个具体的实现类的实例 。但是它们的目的不一样,代理模式做的是增强原方法的活,适配器做的是适配的话。
8、桥接模式
将两个能够独立变化的部分分离开来
桥接模式有一个抽象和一个接口,其中用接口做桥梁
用接口做桥梁
public interface DrawAPI {
public void drawCircle(int radius, int x, int y);
}
public class GerrnCircle implements DrawAPI{
@Override
public void drawCircle(int radius, int x, int y) {
System.out.println("drawing circle color green: radius: " + radius
+ ",x:" + x + ",y" + y);
}
}
public class RedCircle implements DrawAPI {
@Override
public void drawCircle(int radius, int x, int y) {
System.out.println("drawing circle:" + ",radius:" + radius +
",x:" + x +",y:" + y);
}
}
public abstract class Shape {
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI) {
this.drawAPI = drawAPI;
}
public abstract void draw();
}
public class Circle extends Shape {
private int x;
private int y;
private int radius;
public Circle(int x, int y, int radius, DrawAPI drawAPI) {
super(drawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
@Override
public void draw() {
drawAPI.drawCircle(radius, x, y);
}
}
9、装饰模式
为对象添加新功能
public interface Shape {
void draw();
}
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("Shape:Circle");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Shape:Rectangle");
}
}
public abstract class ShapeDecorator implements Shape {
protected Shape decoratorShape;
public ShapeDecorator(Shape decoratorShape) {
this.decoratorShape = decoratorShape;
}
@Override
public void draw() {
decoratorShape.draw();
}
}
public class RedShapeDecorator extends ShapeDecorator{
public RedShapeDecorator(Shape decoratorShape) {
super(decoratorShape);
}
@Override
public void draw() {
decoratorShape.draw();
setRedBorder(decoratorShape);
}
private void setRedBorder(Shape decoratorShape) {
System.out.println("Border Color: Red");
}
}
10.外观模式
对外提供一个统一的接口用来访问子系统
为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("Shape:Circle");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Shape:Rectangle");
}
}
public class Square implements Shape{
@Override
public void draw() {
System.out.println("Shape square");
}
}
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
private Shape square;
public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
square = new Square();
}
public void drawCircle() {
circle.draw();
}
public void drawRectangle() {
rectangle.draw();
}
public void drawSquare() {
square.draw();
}
}
11.组合模式
将整体与局部进行递归组合,让客户端能够以一种方式对其进行处理
组合模式使得用户对单个对象和组合对象的使用具有一致性。
public class Employee {
private String name;
private String dept;
private int salary;
private List<Employee> subordinates;
public Employee(String name, String dept, int salary) {
this.name = name;
this.dept = dept;
this.salary = salary;
}
public void add(Employee e) {
subordinates.add(e);
}
public void remove(Employee e) {
subordinates.remove(e);
}
public List<Employee> getSubordinates() {
return subordinates;
}
public String toString() {
return ("Employee:[ Name:" + name + ",dept:" + dept + ",salary:"
+ salary + " ]");
}
}
12.享元模式
使用对象池来减少重复对象的创建
享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能。
关键代码:用HashMap存储这些对象
public class Circle implements Shape {
private String color;
private int x;
private int y;
private int radius;
public Circle(String color) {
this.color = color;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setRadius(int radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Circle:Draw()[Color:" + color + ",x:" + x
+ ",y:" + y + ",radius:" + radius);
}
}
public class ShapeFactory {
private static final HashMap<String, Circle> circleMaps = new HashMap<>();
public static Shape getCircle(String color) {
Circle circle = circleMaps.get(color);
if (circle == null) {
circle = new Circle(color);
circleMaps.put(color, circle);
}
return circle;
}
}
行为型模式
13、策略模式
封装不同的算法,算法之间能互相替换
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。策略对象改变context对象的执行算法。
我们将创建一个定义活动的Strategy接口和实现了Strategy接口的实体策略类。Context是一个使用了某种策略的类。
public interface Strategy {
public int doOperation(int num1, int num2);
}
public class OperationAdd implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
public class OperationMultiply implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
14、观察者模式
状态发生改变时通知观察者,一对多的关系
当一个对象被修改时,则会自动通知依赖它的对象。
public class Subject {
private List<Observer> observers = new ArrayList<Observer>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
// 数据已变更,通知观察者们
notifyAllObservers();
}
public void attach(Observer observer){
observers.add(observer);
}
// 通知观察者们
public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
}
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
public class BinaryObserver extends Observer {
// 在构造方法中进行订阅主题
public BinaryObserver(Subject subject) {
this.subject = subject;
// 通常在构造方法中将 this 发布出去的操作一定要小心
this.subject.attach(this);
}
// 该方法由主题类在数据变更的时候进行调用
@Override
public void update() {
String result = Integer.toBinaryString(subject.getState());
System.out.println("订阅的数据发生变化,新的数据处理为二进制值为:" + result);
}
}
public class HexaObserver extends Observer {
public HexaObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
String result = Integer.toHexString(subject.getState()).toUpperCase();
System.out.println("订阅的数据发生变化,新的数据处理为十六进制值为:" + result);
}
}
15.责任链模式
将时间沿着链去处理
责任链模式(Chain of Responsibility)使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象能够处理它
public abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
protected AbstractLogger nextLogger;
public void setNextLogger(AbstractLogger nextLogger) {
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message) {
if (this.level <= level) {
write(message);
}
if (nextLogger != null) {
nextLogger.logMessage(level, message);
}
}
protected abstract void write(String message);
}
public class ConsoleLogger extends AbstractLogger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::logger:" + message);
}
}
public class ErrorLogger extends AbstractLogger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error console::logger:" + message);
}
}
16.模板方法模式
定义一套流程模板,根据需要实现模板中的操作
在模板模式中,一个抽象类公开定义了执行它的方法的模板,它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方法进行。
public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
public void play() {
initialize();
startPlay();
endPlay();
}
}
public class Football extends Game {
@Override
void initialize() {
System.out.println("Football game initialize. Start the game.");
}
@Override
void startPlay() {
System.out.println("Football game started. Enjoy the game.");
}
@Override
void endPlay() {
System.out.println("Football game finished!");
}
}
public class TemplatePatternDemo {
public static void main(String[] args) {
Game footballGame = new Football();
footballGame.play();
}
}
17.状态模式
根据不同的状态做出不同的行为
对象的行为依赖于它的状态,并且可以根据它的状态改变而改变它的相关行为
public interface State {
void doAction(Context context);
}
public class StartState implements State {
@Override
public void doAction(Context context) {
System.out.println("Player is in start state");
}
public String toString() {
return "Start State";
}
}
public class Context {
private State state;
public Context() {
state = null;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return this.state;
}
}
public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context();
StartState startState = new StartState();
startState.doAction(context);
}
}
18.迭代器模式
提供一种方法顺序访问一个聚合对象中的各个元素
这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示
public interface Iterator {
public boolean hasNext();
public Object next();
}
public interface Container {
public Iterator getIterator();
}
public class NameRepository implements Container {
public String names[] = {"Robert", "John", "Julie", "Lora" };
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
int index;
@Override
public boolean hasNext() {
if (index < names.length) {
return true;
}
return false;
}
@Override
public Object next() {
if (this.hasNext()) {
return names[index++];
}
return null;
}
}
}
public class IteratorPatternDemo {
public static void main(String[] args) {
NameRepository nameRepository = new NameRepository();
for(Iterator iterator = nameRepository.getIterator(); iterator.hasNext(); ) {
String name = (String) iterator.next();
System.out.println("name:" + name);
}
}
}
19.备忘录模式
保存对象的状态,在需要时进行恢复
public class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento saveStateToMemento() {
return new Memento(state);
}
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
public class CareTaker {
private List<Memento> mementoList = new ArrayList<Memento>();
public void add(Memento memento) {
mementoList.add(memento);
}
public Memento get(int index) {
return mementoList.get(index);
}
}
20.访问者模式
稳定数据结构中,定义新的操作行为
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。
21.中介者模式
将网状结构转变为星型结构,所有行为都通过中介
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护
public class ChatRoom {
public static void showMessage(User user, String message){
System.out.println(new Date().toString()
+ " [" + user.getName() +"] : " + message);
}
}
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(String name){
this.name = name;
}
public void sendMessage(String message){
ChatRoom.showMessage(this,message);
}
}
22.解释器模式
定义语法,并对其进行解释
这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。
public interface Expression {
public boolean interpret(String context);
}
public class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data){
this.data = data;
}
@Override
public boolean interpret(String context) {
if(context.contains(data)){
return true;
}
return false;
}
}
public class OrExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
public class AndExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null;
public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
public class InterpreterPatternDemo {
//规则:Robert 和 John 是男性
public static Expression getMaleExpression(){
Expression robert = new TerminalExpression("Robert");
Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
}
//规则:Julie 是一个已婚的女性
public static Expression getMarriedWomanExpression(){
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}
public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression();
System.out.println("John is male? " + isMale.interpret("John"));
System.out.println("Julie is a married women? "
+ isMarriedWoman.interpret("Married Julie"));
}
}
23.命令模式
将请求封装成命令,并记录下来,能够撤销与重做
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
public interface Order {
void execute();
}
public class Stock {
private String name = "ABC";
private int quantity = 10;
public void buy(){
System.out.println("Stock [ Name: "+name+",
Quantity: " + quantity +" ] bought");
}
public void sell(){
System.out.println("Stock [ Name: "+name+",
Quantity: " + quantity +" ] sold");
}
}
public class BuyStock implements Order {
private Stock abcStock;
public BuyStock(Stock abcStock){
this.abcStock = abcStock;
}
public void execute() {
abcStock.buy();
}
}
public class SellStock implements Order {
private Stock abcStock;
public SellStock(Stock abcStock){
this.abcStock = abcStock;
}
public void execute() {
abcStock.sell();
}
}
public class Broker {
private List<Order> orderList = new ArrayList<Order>();
public void takeOrder(Order order){
orderList.add(order);
}
public void placeOrders(){
for (Order order : orderList) {
order.execute();
}
orderList.clear();
}
}
网友评论