Prototype Pattern
Java
Prototype
/* 깊은 복사를 위해 Serializable 필요 */
public class Manager<T extends Serializable> {
private HashMap<String, T> showcase = new HashMap<>();
public void register(String prototypeName, T prototype) {
showcase.put(prototypeName, prototype);
}
public T createClone(String prototypeName) {
T target = showcase.get(prototypeName);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(target);
oos.close();
baos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
ois.close();
bais.close();
return (T) ois.readObject();
} catch (IOException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
}
ConcretePrototype
/* 깊은 복사를 위해 Serializable 필요 */
public interface Character extends Serializable {
void attack();
void block();
}
public class Player implements Character {
@Override
public void attack() {
System.out.println("Player - attack!");
}
@Override
public void block() {
System.out.println("Player - block!");
}
}
public class Monster implements Character {
@Override
public void attack() {
System.out.println("Monster - attack!");
}
@Override
public void block() {
System.out.println("Monster - block!");
}
}
Client
public class Main {
public static void main(String[] args) {
Manager<Character> manager = new Manager<>();
Player playerOriginal = new Player();
Monster monsterOriginal = new Monster();
manager.register("player", playerOriginal);
manager.register("monster", monsterOriginal);
Character playerClone = manager.createClone("player");
Character monsterClone = manager.createClone("monster");
print(playerOriginal, playerClone);
print(monsterOriginal, monsterClone);
}
private static void print(Character original, Character clone) {
original.attack();
original.block();
clone.attack();
clone.block();
System.out.println("같은 참조를 갖는가? " + (original == clone));
System.out.println();
}
}
/*
Player - attack!
Player - block!
Player - attack!
Player - block!
같은 참조를 갖는가? false
Monster - attack!
Monster - block!
Monster - attack!
Monster - block!
같은 참조를 갖는가? false
*/
C#
namespace PrototypePattern
{
class Program
{
static void Main(string[] args)
{
Manager manager = new Manager();
Character player = new Player();
manager.Register("player", player);
Character playerClone = manager.CreateClone("player");
playerClone.attack();
Console.WriteLine(player == playerClone);
}
}
/* Client */
public class Manager
{
private static Dictionary<string, Character> showcase = new Dictionary<string, Character>();
public void Register(string key, Character prototype)
{
showcase.Add(key, prototype);
}
public Character CreateClone(string key)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, showcase[key]);
ms.Position = 0;
return formatter.Deserialize(ms) as Character;
}
}
}
/* Prototype */
public interface Character
{
void attack();
void block();
}
/* ConcretePrototype */
[Serializable]
public class Player : Character
{
public void attack()
{
Console.WriteLine("Player - attack!");
}
public void block()
{
Console.WriteLine("Player - block!");
}
}
/* ConcretePrototype */
[Serializable]
public class Monster : Character
{
public void attack()
{
Console.WriteLine("Monster - attack!");
}
public void block()
{
Console.WriteLine("Monster - block!");
}
}
}