技術情報
- 2020年11月02日
- 技術情報
Composite Design Pattern
Composite is a structural design pattern that allows you to compose objects into tree structures and then work with these structures as if they were individual objects.
The application needs to manipulate a hierarchical collection of “primitive” and “compound” objects. Processing of a primitive object is handled in one way and processing of a composite object is handled differently. You don’t want to have to query the “type” of each object before trying to process it.
Define an abstract base class (Component) that specifies the behavior to be exerted uniformly on all primitive and composite objects. Subclass the Primitive and Composite classes outside of the Component class. Each composite object “docks” itself only with the abstract type component, since it manages its “children”.
Use this pattern whenever you have “compounds that contain components, each of which could be a compound.”
Let’s look at the example I wrote as below.
PHP Code Sample
<?php
/**
* This is the common interface of the composite pattern, declares the necessary operations here.
* this might be a set of complex operations under here in a real world application.
*/
interface Common
{
public function report();
}
/**
* Leaf class where there is no any children under this.
*/
class Individual implements Common
{
private $name;
private $total;
public function __construct($name,$total)
{
$this->name = $name;
$this->total = $total;
}
public function report()
{
echo "$this->name got $this->total\n";
}
}
/**
* composite class where has complex component structure.
* getting to each target children to get the final result
*/
class Composition implements Common
{
public $report_list = [];
public function addRecord($list)
{
$this->report_list[] = $list;
}
/**
* traversing child nodes.
*/
public function report()
{
foreach($this->report_list as $list) {
$list->report();
}
}
}
/**
* client code can now access both individual and composite class without acknowleding the concrete implementations.
*/
$p1 = new Individual("Mg Mg",100);
$p2 = new Individual("Hla Hla",200);
$list = new Composition();
$list->addRecord($p1);
$list->addRecord($p2);
$list->report();
?>
C# Code Sample
using System;
using System.Collections.Generic;
namespace HelloWorld
{
/**
* This is the common interface of the composite pattern, declares the necessary operations here.
* this might be a set of complex operations under here in a real world application.
*/
interface Component
{
string report();
}
/**
* Leaf class where there is no any children under this.
*/
class Individual : Component
{
private string _name;
private int _total;
public Individual(string name,int total)
{
this._name = name;
this._total = total;
}
public string report()
{
return _name + " got " + _total;
}
}
/**
* composite class where has complex component structure.
* getting to each target children to get the final result
*/
class Composition : Component
{
protected List<Component> _lists = new List<Component>();
public string report()
{
int i = 0;
string result = "";
foreach (Component component in this._lists)
{
result += component.report();
if (i != this._lists.Count - 1)
{
result += "\n";
}
i++;
}
return result;
}
public void Add(Component component)
{
this._lists.Add(component);
}
}
class Program
{
static void Main(string[] args)
{
/**
* client code can now access both individual and composite class without acknowleding the concrete implementations.
*/
var p1 = new Individual("Mg Mg", 100);
var p2 = new Individual("Hla Hla", 200);
var list = new Composition();
list.Add(p1);
list.Add(p2);
Console.Write(list.report());
}
}
}
By Yuuma.
yuuma at 2020年11月02日 11:00:04
- 2020年10月30日
- 技術情報
[Laravel] Eloquentとページネーション(1)
nishida at 2020年10月30日 10:00:58
- 2020年10月26日
- 技術情報
Adapter Design Pattern
The adapter is a structural design pattern that enables the collaboration of objects with incompatible interfaces.
You can create an adapter. This is a special object that converts an object’s interface so that another object can understand it.
An adapter wraps one of the objects to hide the complexity of the conversion that occurs behind the scenes. The wrapped object is not even aware of the adapter. For example, you can wrap an object that operates in meters and kilometers with an adapter that converts all data to imperial units such as feet and miles.
Adapters can not only convert data into various formats, they can also help objects with different interfaces to collaborate. Is that how it works:
The adapter gets an interface, compatible with one of the existing objects.
With this interface, the existing object can safely call the adapter’s methods.
Upon receiving a call, the adapter passes the request to the second object, but in the format and order expected by the second object.
Sometimes it is even possible to create a bi-directional adapter that can convert calls in both directions.
Lets look at the example I created as below.
PHP Sample Code
<?php
/**
* The original interface that is working as normal
*/
interface Socket
{
public function input();
}
/**
* This is the simple class that follows the existing target interface `Socket`
*/
class twoPinSocket implements Socket
{
public function input()
{
echo "two pin input";
}
}
/**
* This is the conversion class (might be 3rd party service code as well) that will be used later in adapter class.
*/
class conversion
{
public function changetoThreePin()
{
echo "changed to three pin => three pin input";
}
}
/**
* This is the adapter class implementing the original target interface linking with conversion class.
* this will product the format that is second object want.
*/
class threePinSocket implements Socket
{
private $conversion;
public function __construct(conversion $conversion)
{
$this->conversion = $conversion;
}
public function input()
{
$this->conversion->changetoThreePin();
}
}
/**
* The existing twoPinSocket class that follows the target interface.
*/
$socket = new twoPinSocket();
echo $socket->input();
/**
* threePinSocket conversion that follows target interface using conversion adapter
*/
$conversion = new conversion();
$socket = new threePinSocket($conversion);
echo $socket->input();
?>
C# Sample Code
using System;
namespace HelloWorld
{
/**
* The original interface that is working as normal
*/
public interface Socket
{
string input();
}
/**
* This is the simple class that follows the existing target interface `Socket`
*/
class TwoPinSocket : Socket
{
public string input()
{
return "two pin input";
}
}
/**
* This is the conversion class (might be 3rd party service code as well) that will be used later in adapter class.
*/
class Conversion
{
public string change()
{
return "changed 2pin to 3pin";
}
}
/**
* This is the adapter class implementing the original target interface linking with conversion class.
* this will product the format that is second object want.
*/
class ThreePinSocket : Socket
{
private readonly Conversion _conversion;
public ThreePinSocket(Conversion conversion)
{
this._conversion = conversion;
}
public string input()
{
return this._conversion.change();
}
}
public class Program
{
public static void Main(string[] args)
{
/**
* The existing twoPinSocket class that follows the target interface.
*/
Socket socket = new TwoPinSocket();
Console.WriteLine(socket.input());
/**
* threePinSocket conversion that follows target interface using conversion adapter
*/
Conversion conversion = new Conversion();
Socket socket = new ThreePinSocket(conversion);
Console.WriteLine(socket.input());
}
}
}
By Yuuma
yuuma at 2020年10月26日 11:00:37
- 2020年10月23日
- 技術情報
[A5:SQL Mk-2] レコードのバックアップと復元、およびinsert文の生成について
nishida at 2020年10月23日 10:00:09
- 2020年10月19日
- 技術情報
Bridge Design Pattern
Bridge is a structural design pattern that allows you to divide a large class or a set of closely related classes into two separate hierarchies (abstraction and implementation) that can be developed independently of each other.
Bridge is a synonym for the expression “handle / body”. This is a design mechanism that encapsulates an implementation class within an interface class. The first is the body and the second is the handle. The user sees the identifier as the actual class, but the work is done in the body. “The idiom for the handle / body class can be used to decompose a complex abstraction into smaller, more manageable classes. The idiom can reflect the sharing of a single resource by multiple classes that control access to it (for example, the count of references)”.
- Decouple an abstraction from your implementation so that the two can vary independently.
- Publish the interface in an inheritance hierarchy and hide the implementation in its own inheritance hierarchy.
Lets take a look at the code samples I created as below.
PHP Code Sample
<?php
/**
* This is the original application interface
* where we place the methods need to develop from its concrete sub classes
*/
interface ApplicationInterface
{
public function setDbDriver(DbDriver $dbDriver);
public function query($query);
}
/**
* This abstract class will implements the interface as we have to reference the next hierarchy object here.
* After that we can access the methods of their sub concrete classes in our sub classes. see below.
*/
abstract class Application implements ApplicationInterface
{
protected $dbDriver;
public function setDbDriver(DbDriver $dbDriver)
{
$this->dbDriver = $dbDriver;
}
}
/**
* Concrete sub classes of the original class working with the reference object's method.
*/
class android extends Application
{
public function query($query)
{
$query .= "\n\n running android app query\n";
return $this->dbDriver->handleQuery($query);
}
}
class ios extends Application
{
public function query($query)
{
$query .= "\n\n running ios app query\n";
return $this->dbDriver->handleQuery($query);
}
}
/**
* This is the interface that need to be referenced by original class instead of inheritance.
*/
interface DbDriver
{
public function handleQuery($query);
}
/**
* Concrete classes that will have the detail implementations of the interface.
*/
class MysqlDriver implements DbDriver
{
public function handleQuery($query)
{
echo "\nUsing the mysql driver: ".$query;
}
}
class OracleDriver implements DbDriver
{
public function handleQuery($query)
{
echo "\nUsing the oracle driver: ".$query;
}
}
//client code
// client doesn't need to know any implementation details.
// Just build the original concrete class and inject the concrete object that will be referenced.
$android = new android();
$android->setDbDriver(new MysqlDriver());
echo $android->query("select * from table");
$android->setDbDriver(new OracleDriver());
echo $android->query("select * from table");
$ios = new ios();
$ios->setDbDriver(new MysqlDriver());
echo $ios->query("select * from table");
$ios->setDbDriver(new OracleDriver());
echo $ios->query("select * from table");
C# Code Sample
using System;
using System.Collections.Generic;
namespace HelloWorld
{
/**
* Two Original classes referencing the same DbDriver which is the next hierarchy object
* After that we can access the methods of their sub concrete classes in our sub classes. query method in this case
*/
class ApplicationInterface
{
protected DbDriver _dbdriver;
public ApplicationInterface(DbDriver dbdriver)
{
this._dbdriver = dbdriver;
}
public virtual string setDbDriver()
{
return "Base DB Driver:" +
_dbdriver.query();
}
}
class RefinedAbstraction : ApplicationInterface
{
public RefinedAbstraction(DbDriver dbdriver) : base(dbdriver)
{
}
public override string setDbDriver()
{
return "Refined DB Driver:" +
base._dbdriver.query();
}
}
/**
* This is the interface that need to be referenced by original class instead of inheritance.
*/
public interface DbDriver
{
string query();
}
/**
* Concrete classes that will have the detail implementations of the interface.
*/
class MysqlDriver : DbDriver
{
public string query()
{
return "Using the mysql driver:\n";
}
}
class OracleDriver : DbDriver
{
public string query()
{
return "Using the oracle driver:.\n";
}
}
// client doesn't need to know any implementation details.
// Just build the original class and inject the concrete object that will be referenced.
class Client
{
public void ClientCode(ApplicationInterface applicationInterface)
{
Console.Write(applicationInterface.setDbDriver());
}
}
class Program
{
static void Main(string[] args)
{
Client client = new Client();
ApplicationInterface applicationInterface;
applicationInterface = new ApplicationInterface(new MysqlDriver());
client.ClientCode(applicationInterface);
Console.WriteLine();
applicationInterface = new RefinedAbstraction(new OracleDriver());
client.ClientCode(applicationInterface);
}
}
}
yuuma at 2020年10月19日 11:00:17