// big brother | Java
Prints: whiletruetypecode.threadless.com
Facebook: facebook.com/whiletruetypecode

seen from United States

seen from Netherlands
seen from United States
seen from United States

seen from United States
seen from Canada
seen from United States
seen from United States
seen from Malaysia
seen from United States
seen from United States
seen from T1
seen from United States

seen from Canada
seen from United States

seen from United States

seen from Türkiye
seen from France
seen from Malaysia
seen from United Kingdom
// big brother | Java
Prints: whiletruetypecode.threadless.com
Facebook: facebook.com/whiletruetypecode
Observer Design Pattern Tutorial with Java Coding for Beginners | Obser...
Hello friends, a #video on #observer #design #pattern with #Java #coding #example is published on #codeonedigest #youtube channel. Learn #observerdesignpattern & #programming #coding with codeonedigest.
#observerdesignpattern #observerdesignpatternjava #observerdesignpatternexample #observerdesignpatternspringboot #observerdesignpatterntutorial #observerdesignpatternexplained #observerdesignpatternjavacode #observerpattern #observerpatterninjava #observerpatternrealworldexample #observerpatterninpython #observerpatternimplementationinjava #observerpatternexample #observerpatternadvantages #observerpatterninsoftwaredesign #observerdesignpattern #observerdesignpattern #observerdesignpatterninjava #observerdesignpatterninhindi #observerdesignpatternrealworldexample #observerdesignpatternexample #observerdesignpatternjavaexample #observerdesignpatternintent #softwaredesignpattern #designprinciple #designpatterns #viral #trending
Design Pattern: Observer Pattern in Java
Design Pattern: Observer Pattern in Java
We use simple examples and diagrams to describe the concept of observer pattern. We also give a simple implementation of the observer pattern in Java. What is Observer Pattern The observer pattern defines a one-to-many relationship between two kinds of objects. The one side is called Subject, which maintains a list of Objects (called observers), and automatically notify each of the observers if…
View On WordPress
The Observer pattern and Action Queues
There is a well-know design pattern called publish-subscribe or the Observer model. The problem this model attempts to solve is one in which a object requires one or more parties to act on it when it changes to a particular state. A concrete example of this event handlers in GUIs including the DOM. Actions made be associated with button presses.
The Observer model seperates the subject from the parties (observers) that act on it. Observers register the interest with the subject. When the subject changes to the desired state, it notifies each of the registered observers.
In PHP, a subject class might be modeled like this:
class Subject { private $Q = array(); function Attach($O) { array_push($this->Q, $O); } function Detach($O) { for($i=0; $i < count($Q); $i++) { if ($Q[$i] == $O) { array_splice($this->Q, $i, 1); break; } } } function Notify() { foreach($this->Q as $O) { $O->Update($this); } } }
The Attach() and Detach() methods are the API by which Observers register or unregister their interest in a Subject object. When the subject changes into an interesting state, its Notify() method is called. This method in turn calls the Observer Update() method with a reference to the current Subject object. An Observer class might look like this:
class Observer { function Update($S) { // Do something interesting } }
As you can see, an Observer need only implement one well-known method, Update(). This arrangement nicely decouples the Subject from the Observers.
There may be times when a less formal, more functional mechanism is desirable. What if you want just want certain actions to happen on an object when an interesting state obtains? You might use what I call an Action queue to do this. An Action Queue is simply an array of function references that are called by an object at an interesting time. Here's what an Action queue might look like:
class MyClass { private $Q = array(); function Attach($name, $func) { $this->Q[$name] = $func; } function Detach($name) { unset($this->Q[$name]); } function Notify() { foreach ($this->Q as $n=>$func) { $func($this); } } }
As you can see, there is no need for an Observer class. Bits of functionality created with create_function() can be attached ad hoc to this class, as the following snipet shows:
$appender = create_function('$obj', 'return "Got => ".\$obj'); $MyClassObj->Attach("append", $appender);
Because these code bits are anonymous, an arbitary name is required during the Attach phase in the event that you might want to remove the behavior later.
New Post has been published on Mocco
New Post has been published on http://mocco.sk/design-patterns-in-wordpress-the-singleton-pattern/
Design Patterns in WordPress: The Singleton Pattern
Throughout this series, weâre taking a look at the significance of design patterns and the roles that they play in WordPress development.
In the first post in the series, we took a high-level survey and even reviewed the Observer Pattern to see how itâs possible to register various functions or objects with certain events that occur within the lifecycle of an application.
In this post, whereâs going to take a look at the Singleton Pattern.
Specifically, weâre going to take a look at the definition of the pattern and how it works, weâre going to review a diagram of what the architecture of the pattern looks like, weâll cover some sample code for the pattern, and then weâll discuss the advantages of the pattern as it relates to WordPress development.
The Singleton Pattern
Wikipedia defines the Singleton Pattern as follows:
In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object.
Perhaps a simpler way of explaining the pattern is this: The Singleton Pattern ensures that a class can only have one instance and it provides a single way to retrieve an instance of itself.
So Why Does This Matter in WordPress?
As far as theme development is concerned, I personally donât see much of a use for it unless youâre bundling some type of helper class or library with your theme; however, if youâre building plugins, then this can be exceptionally useful.
As of now, there are really only a handful of ways to instantiate plugins (excluding widgets – thatâs another topic) within WordPress:
You can instantiate the plugin at the bottom of your plugin file, but this can lead to an orphaned object
You can stick the plugin in the PHP $GLOBALS collection, but this can be dangerous as you could trash something that already exists or itâs making the collection needlessly larger
If you instantiate it with, say, each page load then the data isnât being persisted unless you serialize and hammer the database each time the plugin is instantiated
None of the above are particularly good strategies (although you could make a case that they all work).
However, we care more than just getting something to work, right? We want it to work and we want an elegant solution to the problem. This is where design patterns – more specifically, the Singleton Pattern – come into play.
What It Looks Like
First, letâs take a look at a diagram of the Singleton Pattern. Check out the diagram below, then weâll talk about the specifics after the image:
So here are the key features of the Singleton Pattern:
There is a private, static instance variable defined in the attributes that is used to maintain a reference to the class
The constructor has been marked as private
There is a public static function named get_instance which is used to return an instance of the class
Nothing too complicated, but I think reviewing the code for the Singleton Pattern goes a long way in making it a bit clearer, so letâs do that now:
class Foo { /*--------------------------------------------* * Attributes *--------------------------------------------*/ /** Refers to a single instance of this class. */ private static $instance = null; /*--------------------------------------------* * Constructor *--------------------------------------------*/ /** * Creates or returns an instance of this class. * * @return Foo A single instance of this class. */ public function get_instance() { if ( null == self::$instance ) { self::$instance = new self; } return self::$instance; } // end get_instance; /** * Initializes the plugin by setting localization, filters, and administration functions. */ private function __construct() { } // end constructor /*--------------------------------------------* * Functions *--------------------------------------------*/ } // end class Foo::get_instance();
Obviously, thereâs been a lot of code left out of the above class, but the patternâs principles remain.
Notice that we have a private, static instance variable thatâs used to refer to this class. Specifically, itâs set in the get_instance function whereas the constructor has been marked as private.
Typically, when instantiating classes, the constructor is the function that is called whenever we initialize classes; however, in this case, the constructor is marked as private.
So what gives?
Notice that we have a public get_instance function just above the constructor. This function literally checks to see if the static instance variable is null and, if so, creates a new instance of the class (which it can do since itâs within the context of the class); otherwise, it returns the current instance.
This is how no more than a single instance of a class is created.
Finally, note that we instantiate the class not with the standard new keyword, but by calling get_instance. Not only that, but we also get future references to the class by using the same method.
So, for example, letâs say that youâre working in another template and you need to call a function – say bar() – that exists in your plugin. In that case, youâd do something like this:
$foo = Foo::get_instance(); $foo->bar();
Pretty neat, isnât it?
The Advantages of the Singleton Pattern
Despite the fact that weâve covered the Singleton Pattern from an architectural and a practical standpoint, we havenât actually talked about the advantages of the pattern.
Generally speaking:
The Singleton Pattern prevents other objects or clients from duplicating instances of the class. This makes sure that thereâs only one copy of the data maintained at any given time. All access to the object is done so by the single instance.
We have a wide array of flexibility when it comes to implementation because we can actually impact the instantiation process (though this is a bit out of scope for this particular post).
Perhaps the largest drawback from using the pattern is lack of clarity that the plugin actually uses the pattern. If someone tries to instantiate the class, instantiation will fail because thereâs no public constructor.
As such, documentation is key.
Conclusion
Whether youâve seen them before or this is your first foray into design patterns, the Singleton Pattern is arguably the simplest design pattern there is. Itâs easy to implement, and it provides a significant source of functionality when implemented correctly especially as it relates to web applications.
In the next post, weâll take a look at another pattern – the Simple Factory Pattern – which is useful when you have a number of classes each of which has a unique purpose and that will be needed based on certain input criteria.
Other parts in this series:Design Patterns in WordPress: An Introduction
Check out the original source here.
Observer Pattern with Python Decorators
Hi,
In this post, I will try to implement Observer Pattern [GoF] using Python decorators. For those who do not know what the Observer Pattern is here is an incomplete summary. Observer pattern is a design pattern to handle change and notification mechanism for an changing object and other objects that are interested in these changes. The most-widely used example for this pattern is this: A spreadsheet, pie chart, bar chart etc, are derived from same data and we want to ensure that all of them are up to date when we change the underlyingg data.
前端计算规则联动引擎
这个方案是之前交易平台重构的时候重新设计的,用于解决目前购物车确认下单里,复杂交易金额计算规则带来的维护问题。
目前淘宝的购物车确认下单金额计算包含了各个单品的金额总和,运费平台,优惠平台,商城积分等几个大部分,而其中每个部分内部又有自身独立的运算。比如运费还包含快递,邮政和COD(货到付款),快递的计算规则由各个卖家设定的运费模版决定,不同的商品有不同的运费模版,这样总运费就不是简单的商品*快递费了;COD里除了快递的运费模版之外,还需要对最终运费进行取整,这个取整规则又根据不同的价格区间而不同,根据不同的COD运费模版而不同。再比如优惠平台,包括单品优惠,店铺优惠和跨店优惠(活动促销)等,这些优惠信息都跟卖家相关,统一由优惠系统集中提供,每次修改数量,收货地址的时候影响了原始总价格,然后就需要重新计算优惠金额,从而影响了最终实际价格。
上面仅仅是最简单的列举了目前购物车确认下单里的计算逻辑。前端在页面需要实时的根据用户的修改作出计算,告诉用户当前的实际付款金额。这样复杂的金额计算规则,是整个购物系统经过好几年一步一步发展过来的。而以往的前端代码里,根据业务的变化,修改具体的计算代码,一步一步地变脏,变乱。代码的强烈耦合,导致有些前端无从了解具体业务,出现了直接根据DOM结构来计算金额的窘境。
我们经常讲代码是反映业务逻辑的,而不需要太多的注释来解释。从这个角度出发,要求我们更进一步的从代码的角度理解和抽象业务逻辑。从前端的角度,我们将每个具体的计算逻辑抽象为以下几点:
计算公式(计算逻辑)
公式所需要的变量
公式代入具体变量后的值(计算结果)
这样讲似乎看不出跟具体业务的关系,我们拿商品数量这个简单的例子来解释下:
计算公式:商品价格*商品数量
公式所需要的变量:商品价格:页面某个Tag;商品数量:输入框
公式代入具体变量后的值:算出来后传递出去。
具体到代码层面,还需要再进一步提出问题:
一、计算公式用什么方式描述?
可以采用原生的JS代码来描述具体的逻辑,因为维护这段代码的都是前端,能够理解。
二、变量通过什么方式传递?变量的类型是什么?
另外,因为我们计算的过程都是数字,所以为了简化,我们假设所有的变量都是数字。
三、计算结果通过什么方式传出?通过什么方式接收?
我们都知道观察者模式(自定义事件)最适合拿来做逻辑隔离(解耦),这样满足了我们不希望每个业务混杂在一起的初衷,每个业务规则可以只关心自己的计算,然后通过自定义事件接收变量;另外一方面,有些计算数据可能是等待一个异步结果,比如优惠部分的结果都需要等待Ajax的返回,那可以把这部分trigger的代码放到异步回调里。伪代码如下:
quantityPrice.bind('inputChange', function(e) { this.trigger('quantityPriceChange', price * e.quantity); })
计算完成,通过trigger将结果抛出,抛出之后就等待其他监听方来接收了,自己也再不用关心自己被谁依赖了。
通过这三个问题,我们确定了一个基本的计算规则怎么和其他规则进行交互,以及交互过程中怎么传递数据。接下来,我们再进一步。我们知道所有规则都是通过自定义事件进行接收参数和抛出计算结果,那为何不将这一步再封装一下,从业务的角度重新设计一下API。
这里,我们就可以将这个计算规则独立抽象为一个类,这个类包装了特定规则的计算方法,也声明了该规则依赖了哪些变量等。我们将初始化参数设计为:
new Rule('quantityPrice', function(quantity, price) { return quantity * price }, { parents: ['quantity', 'price'] })
这个初始化过程就封装了上述自定义事件绑定的过程。然后也声明了该规则依赖了商品价格和数量这两个变量。所有的计算规则都可以通过这个简单的API来描述。
进一步,我们追溯到quantityPrice的上游price,因为price和quantity这两个已经没有上游规则,这里我们再独立一个入口,提供给最顶的变量使用:
new Rule('price', function(e) { return parseInt(e.price, 10) }, { vars: {price: $('#price').text() } })
有些时候,我们还遇到一些会动态变化的变量,比如商品数量,是在用户操作后才变化的,这时候,我们还需要一个手动触发更新的接口:
var quantityRule = new Rule('quantity', function(e) { return parseInt(e.quantity, 10) })
我们通过update方法来传递特定的变量,同时手动触发计算:
quantityRule.update({ quantity: $('#quantity').val() })
这个方法就放在具体的input.onChange事件绑定即可。合并这两步,我们实际上还可以将quantityPrice这个规则简化为:
var quantity = new Rule('quantity', function(price, e) { return e.quantity * price }, { parents: ['price'] }) input.bind('change', function() { quantity.update({quantity: $(this).val() }) })
在这个定义里,我们在声明parents: ['price']的时候,自动帮quantity这个对象监听了price的变动,update之后,又自动做了一步trigger('quantity'),即相当于:
Rule.bind('price', function(e) { quantity.caculate(e.result, { quantity: this.vars.quantity }) Rule.trigger('quantity', {result: this.result}) })
这里出现了一个Rule执行on和trigger。传统的观察者模式里,下游规则要监听上游规则,需要把下游规则的代码写到上游规则的绑定代码里,这样又违背了我们解耦的初衷,所以采用事件中心的概念,集中一个对象来执行监听和广播。
将这些独立的节点联合起来之后,我们可以看到一个完整的运算网络:
这里我们已经完成了大部分工作,实现了具体业务的隔离,也重新调整了业务代码之间交互的方式,从而达到了业务解耦的目的。解耦之后,我们可以对每个规则独立调优,分配给不同的人员负责,独立文档,独立单元测试,等等。
前面的规则,都是设计为单个规则,单个计算的,而遇到同样的规则使用多次的时候,就乱套了。即,以上设计无法用于多实例的场景。我们知道,只要拿到了实例,那是很容易进行绑定和通信的,但是拿到实例意味着监听方不仅需要知道上游规则的名称,还需要得到上游规则的对象实例,意味着两个规则已经形成强耦合,又违背了我们不希望两个规则耦合的初衷。
在事件中心的设计里,事件监听和触发都是一个对象,我们采用另外的方式来实现实例管理:对事件进行分组,用事件名来描述实例,即触发和监听的时候,采用这种事件名:
Rule.trigger('{groupName}:{ruleName}', result)
这样,监听方就需要对'groupName'进行管理,维护上游传下来的分组信息,形成一个自定义的变量表,从而达到一个对象管理多个实例的目的。
Rule.bind('{groupName}:{ruleName}', function(e) { self.vars[e.groupName] = e.result; })
而且,在计算的时候,也需要选择正确的分组变量,进行计算。
self.vars[e.groupName] * price
整个规则对象可以整理为这样:
每个规则就像一个多入口多出口的管道一样,自由组装,从而形成一个复杂的多实例联动网络。
这样的设计,对于整个计算过程而言是一个整体,我们可以统一对整个过程做集中优化,比如运算缓存。
在上游的计算结果通知下游的过程中,每次计算都会被触发,这样对于修改数量这个很顶级的手动操作而言,可能会导致相当多的下游重复计算。这时候我们可以在引擎通知下游的时候,做一下运算缓存,如果当前计算结果跟上一次是一样的,那么就没有必要重复通知了,因为对于下一个计算规则,所有变量都是一样的,再算一次没有任何意义。(这个思路来源于JavaScript Memorization)
if (this.cache[e.targetGroup] !== this.result) Rule.trigger('{groupName}:{ruleName}', this.result)
这样优化之后,整体重复运算过程少了至少1/3。
总的来说,这个框架的具体实现可能只适用于电子商务相关的金额计算过程抽象,在重构迁移完成之后对每个计算过程做优化,还是很简单的事情,而且单元测试也很容易保证。
比如COD的运算,基本上就是把运算方法迁移过来,然后直接写多一个规则调用这个方法,调整一下传参的方式即可,原来的单元测试代码全部可以保留。后期在优化的时候,对每个规则都写测试用例,规则分散个各个业务模块里,只要页面初始化就会加入,分工也简单了很多,每个人负责好自己的业务模块,写好自己的规则代码和测试代码,规则之间联动的事情,交给联动引擎就ok了。
自动事件绑定和基于文本的实例管理,这两者还都不容易把握,整个框架开发过程中花了很大心思来加强这两部分的稳定性。相比具体的实现,这两个模型倒是可以借鉴用到其他地方去。
PHP Observer pattern using PHP SPL Library
see PHP SPL Library
/** * Login is observable */ class Login implements SplSubject { private $_observers; private $_status; function __construct() { $this->_observers = new SplObjectStorage(); } function attach(SplObserver $obs) { // requires that observers must be of type LoginObserver to be attached if (is_a($obs, "LoginObserver")) { $this->_observers->attach($obs); } else { throw new Exception("Only 'LoginObservers' can be attached to the Subject/Observable 'Login'"); } } function detach(SplObserver $obs) { $this->_observers->detach($obs); } // function to notify observers something has changed function notify() { foreach ($this->_observers as $obs) { $obs->update($this); } } function login() { echo "Logging in ... "; $this->_status = rand(1,2); $this->notify(); // trigger notification broadcast } function getStatus() { return $this->_status; } } abstract class LoginObserver implements SplObserver { function update(SplSubject $sub) { // requires that subject must be of type Login // ensures that function getStatus() exists if (is_a($sub, "Login")) { $this->doUpdate($sub); } else { throw new Exception("Subject must be od type 'Login'"); } } abstract function doUpdate(Login $login); } class LoginLogger extends LoginObserver { function doUpdate(Login $login) { echo " - Logging status: " . $login->getStatus() . " "; } } class FailedLoginLogger extends LoginObserver { function doUpdate(Login $login) { if ($login->getStatus() == 2) { echo " - Logging FAILED login: " . $login->getStatus() . " "; } } } class NewObserver implements SplObserver { function update(SplSubject $sub) { echo " * From 'NewObserver' ... "; } } $login = new Login(); $login->attach(new LoginLogger()); $login->attach(new FailedLoginLogger()); $login->attach(new NewObserver()); // error !!! unless the line checking Observers to be of type LoginObserver is removed for ($i = 0; $i < 10; $i++) { $login->login(); }
Outputs ...
Logging in ... - Logging status: 1 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 1 Logging in ... - Logging status: 1 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 2 - Logging FAILED login: 2 Logging in ... - Logging status: 1