Flyweight图案是 结构设计模式 因为这种模式提供了减少对象数量的方法,从而改进了应用程序所需的对象结构。当我们需要创建大量类似的对象(比如10个)时,可以使用Flyweight模式 5. ). flyweight对象的一个重要特征是 不变的 。这意味着一旦构建它们,就不能对其进行修改。
为什么我们关心程序中对象的数量?
- 对象的数量减少了内存的使用,并且它设法使我们远离与内存相关的错误,比如 JAVAlang.OutOfMemoryError。
-
虽然用Java创建对象非常快,但我们仍然可以通过共享对象来减少程序的执行时间。
在Flyweight模式中,我们使用 哈希图 它存储对已创建对象的引用,每个对象都与一个键相关联。现在,当客户机想要创建一个对象时,他只需传递一个与之相关联的键,如果该对象已经创建,我们只需获取对该对象的引用,否则它将创建一个新对象,然后将其引用返回给客户机。
内在和外在状态
为了理解内在的和外在的状态,让我们考虑一个例子。
假设在文本编辑器中输入字符时,创建了字符类的对象,字符类的属性为{name,font,size}。我们不需要每次客户端输入字符时都创建一个对象,因为字母“B”与另一个字母“B”没有区别。如果客户机再次输入a“B”,我们只需返回之前已经创建的对象。现在所有这些都是内在状态(名称、字体、大小),因为它们可以在不同的对象之间共享,因为它们彼此相似。
现在我们向Character类添加了更多属性,它们是row和column。它们指定字符在文档中的位置。现在,即使对于相同的字符,这些属性也不会相似,因为没有两个字符在文档中具有相同的位置,这些状态被称为外部状态,并且它们不能在对象之间共享。
实施: 我们在战争游戏中创造恐怖分子和反恐分子 反击 .所以我们有两门课,一门课 T 恐怖分子( T )还有其他的 C 倒数 T 恐怖分子( 计算机断层扫描 ).每当玩家要武器时,我们都会给他指定所要的武器。在任务中,恐怖分子的任务是放置炸弹,而反恐怖分子必须扩散炸弹。
为什么在本例中使用Flyweight设计模式? 这里我们使用飞重设计模式,因为这里我们需要减少玩家的物品数量。现在我们有n个玩家在玩CS 1.6,如果我们不遵循飞重设计模式,那么我们将不得不创建n个对象,每个玩家一个。但现在我们只需要创建两个对象,一个用于恐怖分子,另一个用于反恐,我们将在需要时反复使用。
固有状态: 对于这两种类型的玩家来说,“任务”都是一种固有状态,因为这对于T/CT总是相同的。我们可以有一些其他状态,比如它们的颜色或任何其他属性,它们对于各自的恐怖分子/反恐怖分子类别中的所有恐怖分子/反恐怖分子都是相似的。
外在状态: 武器是一种外在状态,因为每个玩家都可以携带自己选择的任何武器。客户端本身需要将武器作为参数传递。
// A Java program to demonstrate working of // FlyWeight Pattern with example of Counter // Strike Game import java.util.Random; import java.util.HashMap; // A common interface for all players interface Player { public void assignWeapon(String weapon); public void mission(); } // Terrorist must have weapon and mission class Terrorist implements Player { // Intrinsic Attribute private final String TASK; // Extrinsic Attribute private String weapon; public Terrorist() { TASK = "PLANT A BOMB" ; } public void assignWeapon(String weapon) { // Assign a weapon this .weapon = weapon; } public void mission() { //Work on the Mission System.out.println( "Terrorist with weapon " + weapon + "|" + " Task is " + TASK); } } // CounterTerrorist must have weapon and mission class CounterTerrorist implements Player { // Intrinsic Attribute private final String TASK; // Extrinsic Attribute private String weapon; public CounterTerrorist() { TASK = "DIFFUSE BOMB" ; } public void assignWeapon(String weapon) { this .weapon = weapon; } public void mission() { System.out.println( "Counter Terrorist with weapon " + weapon + "|" + " Task is " + TASK); } } // Class used to get a player using HashMap (Returns // an existing player if a player of given type exists. // Else creates a new player and returns it. class PlayerFactory { /* HashMap stores the reference to the object of Terrorist(TS) or CounterTerrorist(CT). */ private static HashMap <String, Player> hm = new HashMap<String, Player>(); // Method to get a player public static Player getPlayer(String type) { Player p = null ; /* If an object for TS or CT has already been created simply return its reference */ if (hm.containsKey(type)) p = hm.get(type); else { /* create an object of TS/CT */ switch (type) { case "Terrorist" : System.out.println( "Terrorist Created" ); p = new Terrorist(); break ; case "CounterTerrorist" : System.out.println( "Counter Terrorist Created" ); p = new CounterTerrorist(); break ; default : System.out.println( "Unreachable code!" ); } // Once created insert it into the HashMap hm.put(type, p); } return p; } } // Driver class public class CounterStrike { // All player types and weapon (used by getRandPlayerType() // and getRandWeapon() private static String[] playerType = { "Terrorist" , "CounterTerrorist" }; private static String[] weapons = { "AK-47" , "Maverick" , "Gut Knife" , "Desert Eagle" }; // Driver code public static void main(String args[]) { /* Assume that we have a total of 10 players in the game. */ for ( int i = 0 ; i < 10 ; i++) { /* getPlayer() is called simply using the class name since the method is a static one */ Player p = PlayerFactory.getPlayer(getRandPlayerType()); /* Assign a weapon chosen randomly uniformly from the weapon array */ p.assignWeapon(getRandWeapon()); // Send this player on a mission p.mission(); } } // Utility methods to get a random player type and // weapon public static String getRandPlayerType() { Random r = new Random(); // Will return an integer between [0,2) int randInt = r.nextInt(playerType.length); // return the player stored at index 'randInt' return playerType[randInt]; } public static String getRandWeapon() { Random r = new Random(); // Will return an integer between [0,5) int randInt = r.nextInt(weapons.length); // Return the weapon stored at index 'randInt' return weapons[randInt]; } } |
输出:
Counter Terrorist Created Counter Terrorist with weapon Gut Knife| Task is DIFFUSE BOMB Counter Terrorist with weapon Desert Eagle| Task is DIFFUSE BOMB Terrorist Created Terrorist with weapon AK-47| Task is PLANT A BOMB Terrorist with weapon Gut Knife| Task is PLANT A BOMB Terrorist with weapon Gut Knife| Task is PLANT A BOMB Terrorist with weapon Desert Eagle| Task is PLANT A BOMB Terrorist with weapon AK-47| Task is PLANT A BOMB Counter Terrorist with weapon Desert Eagle| Task is DIFFUSE BOMB Counter Terrorist with weapon Gut Knife| Task is DIFFUSE BOMB Counter Terrorist with weapon Desert Eagle| Task is DIFFUSE BOMB
进一步阅读—— Python中的Flyweight方法
参考资料:
- 可重用面向对象软件的要素(四人帮)
- https://en.wikipedia.org/wiki/Flyweight_pattern
本文由 希拉格·阿加瓦尔 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以写一篇文章,然后将文章邮寄给评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。
如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论