一、定义
运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
二、理解
在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题。比如,在围棋中的白子和黑子,各个对象很相似,如果为每一个对象都重新生成一个对象,会造成资源的浪费。享元模式就是将大量对象共有的部分抽取出来,供这些对象共享使用。而这些元素不同的部分,会以参数的形式注入具体享元的相关方法中。
在享元模式中,有以下几种角色:
- 抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
- 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
- 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
- 享元工厂(Flyweight
Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
三、代码示例
棋子中分为白子(具体享元)和黑子(具体享元),它们有自己独有的信息,在棋盘上会有许多棋子,它们的位置不同(非享元)。
可以看到,虽然我们”下了“200个棋子,实际上,我们只用了两个棋子元素(享元),而位置(非共享信息)以参数的形式注入具体享元的相关方法中即xiaqi
i在实际应用中,我们简单打印的白子和黑子的信息可能是许多内容,通过这种方式,节约了资源。每一次只需创建对象的非共享信息即可。
java:
public class Flyweight {
//享元模式:享元工厂(ChessFactory)、抽象享元(Chess、下棋的方法,需要传入一个位置),具体享元(WhiteChess、BlackChess),非共享角色PositonInfo,
public static void main(String[] args) {
//获取黑子与白子
Chess black = ChessFactory.getChess(CHESS_COLOR.BLACK);
Chess white = ChessFactory.getChess(CHESS_COLOR.WHITE);
for (int i = 0; i < 100; i++) {
PositionInfo info = new PositionInfo(i,i);
black.xiaQi(info);
white.xiaQi(info);
}
//可以看到,虽然我们”下了“200个棋子,实际上,我们只用了两个棋子元素(享元),而位置(非共享信息)以参数的形式注入具体享元的相关方法中即xiaqi
//在实际应用中,我们简单打印的白子和黑子的信息可能是许多内容,通过这种方式,节约了资源。每一次只需创建对象的非共享信息即可。
}
}
class PositionInfo {
public Integer x;
public Integer y;
public PositionInfo(Integer x,Integer y){
this.x= x;
this.y = y;
}
}
interface Chess {
void xiaQi(PositionInfo positionInfo);
}
class BlackChess implements Chess {
public String info;
@Override
public void xiaQi(PositionInfo positionInfo) {
System.out.println("下黑子,位置:"+positionInfo.x+"," + positionInfo.y);
System.out.println("棋子的信息:"+this.info);
}
}
class White implements Chess {
public String info;
@Override
public void xiaQi(PositionInfo positionInfo) {
System.out.println("下白子,位置:"+positionInfo.x+"," + positionInfo.y);
System.out.println("棋子的信息:"+this.info);
}
}
enum CHESS_COLOR {
BLACK, WHITE
}
class ChessFactory {
private static Map<CHESS_COLOR,Chess> chessList = new HashMap<>();
static {
BlackChess black = new BlackChess();
black.info= "所有黑棋共有的信息";
chessList.put(CHESS_COLOR.BLACK,black);
White white = new White();
white.info = "所有白棋共有的信息";
chessList.put(CHESS_COLOR.WHITE,white);
}
public static Chess getChess(CHESS_COLOR color) {
return chessList.get(color);
}
}
golang:
func main() {
factory := NewChessFactory()
blackChess := factory.GetChess(BLACK)
whiteChess := factory.GetChess(WHITE)
for i := 0; i < 100; i++ {
positionInfo := new(PositionInfo)
positionInfo.X ,positionInfo.Y= i,i
blackChess.XiaQi(positionInfo)
whiteChess.XiaQi(positionInfo)
}
}
//非享元信息类
type PositionInfo struct {
X int
Y int
}
//享元接口类
type Chess interface {
XiaQi(positionInfo *PositionInfo)
}
type BlackChess struct {
Info string
}
func (chess *BlackChess) XiaQi(info *PositionInfo) {
fmt.Println("下黑子,位置:",info.X,",",info.Y)
fmt.Println("棋子的信息",chess.Info)
}
type WhiteChess struct {
Info string
}
func (chess *WhiteChess) XiaQi(info *PositionInfo) {
fmt.Println("下黑子,位置:",info.X,",",info.Y)
fmt.Println("棋子的信息",chess.Info)
}
type CHESS_COLOR uint8
const (
BLACK CHESS_COLOR= 0
WHITE CHESS_COLOR= 1
)
//享元模式工厂类
type ChessFactory struct {
m map[CHESS_COLOR]Chess
}
//棋子工厂,单例模式
var once sync.Once
var chessFactory *ChessFactory;
func NewChessFactory() *ChessFactory {
once.Do(func() {
chessFactory = new(ChessFactory)
chessFactory.m = make(map[CHESS_COLOR]Chess,2)
blackChess := new(BlackChess)
blackChess.Info = "所有黑棋共有的信息"
chessFactory.m[BLACK] =blackChess
whiteCHess := new(WhiteChess)
whiteCHess.Info = "所有白棋共有的信息"
chessFactory.m [WHITE]=whiteCHess
})
return chessFactory
}
func (factory *ChessFactory) GetChess(color CHESS_COLOR) Chess {
return factory.m[color]
}